Compare commits
855 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
343605ebac | ||
|
|
beec11565c | ||
|
|
26b36dfea1 | ||
|
|
289fd95c3d | ||
|
|
2f79133685 | ||
|
|
e42128e937 | ||
|
|
de38ee4a21 | ||
|
|
612308f281 | ||
|
|
f545a24bbd | ||
|
|
1102cfdf82 | ||
|
|
775f1a59df | ||
|
|
35ae1a28d4 | ||
|
|
842eb11448 | ||
|
|
5976973111 | ||
|
|
91cfb70856 | ||
|
|
09ce595239 | ||
|
|
d4c3567f84 | ||
|
|
39bf116e07 | ||
|
|
10eeeb2490 | ||
|
|
694d9eff19 | ||
|
|
9b9cd36dc9 | ||
|
|
adf65b6761 | ||
|
|
037d3d9090 | ||
|
|
e7364f321d | ||
|
|
14a2a60bf9 | ||
|
|
52c61b115f | ||
|
|
78f2451b2a | ||
|
|
54b3ba39fb | ||
|
|
ede6085429 | ||
|
|
961f295b94 | ||
|
|
848c468b06 | ||
|
|
ba94b9cc94 | ||
|
|
851493a188 | ||
|
|
7e4769e319 | ||
|
|
c0f6ff4d42 | ||
|
|
35e09885fb | ||
|
|
f4b4df8a17 | ||
|
|
953753263c | ||
|
|
809497f707 | ||
|
|
45cc51d48c | ||
|
|
677ce48bea | ||
|
|
d0cc9283e7 | ||
|
|
71e5618380 | ||
|
|
bcb6d02acf | ||
|
|
f116073baf | ||
|
|
6e884615d8 | ||
|
|
d665294669 | ||
|
|
cc43762030 | ||
|
|
9c7c395cc7 | ||
|
|
9680d5bbb2 | ||
|
|
96534d58e5 | ||
|
|
1088492449 | ||
|
|
9b154d12c1 | ||
|
|
e9ee46f302 | ||
|
|
c0714d9c6b | ||
|
|
e728ba1928 | ||
|
|
b94ca2bf80 | ||
|
|
74aae39e4e | ||
|
|
b9bd436b89 | ||
|
|
6eab2adfc1 | ||
|
|
209e1c4d38 | ||
|
|
056da0f922 | ||
|
|
e1a84f2cfe | ||
|
|
b77bd763c0 | ||
|
|
437e6d35eb | ||
|
|
3b06d4ab84 | ||
|
|
3a5ad7712e | ||
|
|
28eb766904 | ||
|
|
4af6c62146 | ||
|
|
96eba8e0ff | ||
|
|
95ccd877a8 | ||
|
|
1815ff4b99 | ||
|
|
c8cc9db7f0 | ||
|
|
b8ebca8d6c | ||
|
|
245a47a848 | ||
|
|
c46f12b97a | ||
|
|
db2ddd6033 | ||
|
|
de1ccc269c | ||
|
|
cd9f53c4b4 | ||
|
|
25afed1d58 | ||
|
|
f3e91634f8 | ||
|
|
6980277aca | ||
|
|
f59a206ab0 | ||
|
|
4eb3283342 | ||
|
|
c2b5979e91 | ||
|
|
cfee7e8b8a | ||
|
|
6fcca7dd44 | ||
|
|
f1edd3a1ea | ||
|
|
d321e0e4fc | ||
|
|
8d89bf9ed0 | ||
|
|
f8b991731f | ||
|
|
77b57ba035 | ||
|
|
08684b31ee | ||
|
|
977f6d210d | ||
|
|
e399b7a085 | ||
|
|
b3634790cd | ||
|
|
3dad4c724e | ||
|
|
d95cf0a3d6 | ||
|
|
14a4c190c9 | ||
|
|
461619411d | ||
|
|
c36c8e11f7 | ||
|
|
11a9dedbaa | ||
|
|
2068ab3211 | ||
|
|
d94bbd4f91 | ||
|
|
28807b6a77 | ||
|
|
d71f664fbb | ||
|
|
f066f0b8d8 | ||
|
|
e30055674d | ||
|
|
d2e1094159 | ||
|
|
73a918ce13 | ||
|
|
6fd7bcf172 | ||
|
|
b88ee8e430 | ||
|
|
ebaeb1bf7c | ||
|
|
bd8ac58b6b | ||
|
|
fcca7fff60 | ||
|
|
b6c18ed171 | ||
|
|
872030fb77 | ||
|
|
90be42c493 | ||
|
|
c4e7254aed | ||
|
|
1b40c2a495 | ||
|
|
81caeaa725 | ||
|
|
1ca9dc6c4e | ||
|
|
8af9e96299 | ||
|
|
70ac65793f | ||
|
|
5d981f56ad | ||
|
|
e16eb8e830 | ||
|
|
58d86cff71 | ||
|
|
cda21694c4 | ||
|
|
7af20516a5 | ||
|
|
2cab9d12d6 | ||
|
|
21985e9a14 | ||
|
|
7827d948d8 | ||
|
|
3b7fa645fb | ||
|
|
28f74bd91d | ||
|
|
0e1fda5c37 | ||
|
|
1f0a4918f2 | ||
|
|
004adac31d | ||
|
|
f58d97d990 | ||
|
|
4b1a0d590f | ||
|
|
bd4db19aee | ||
|
|
5c3640868c | ||
|
|
b4955f0b6e | ||
|
|
cdb99b3588 | ||
|
|
acb46aaed1 | ||
|
|
525c3bd829 | ||
|
|
7caa2bf9ad | ||
|
|
0a9cc2a3b5 | ||
|
|
62f4ced294 | ||
|
|
2a6815c451 | ||
|
|
a0f338eb6f | ||
|
|
0f0d57d855 | ||
|
|
5d42f92c86 | ||
|
|
42a7fda05d | ||
|
|
5810baa021 | ||
|
|
f36f8fe253 | ||
|
|
d56708b45e | ||
|
|
d0b408d679 | ||
|
|
7e3739576f | ||
|
|
565633828c | ||
|
|
061c6325b7 | ||
|
|
66c184a84d | ||
|
|
e3a07ed58c | ||
|
|
e1963a4a3d | ||
|
|
05f6b67b5f | ||
|
|
eb76519d25 | ||
|
|
7b0a0ef4a7 | ||
|
|
48f8d83bdc | ||
|
|
a728817fb5 | ||
|
|
ad422250db | ||
|
|
243c448df9 | ||
|
|
ec7397e4a0 | ||
|
|
245de140f4 | ||
|
|
0ec409f83e | ||
|
|
cc505a3cb2 | ||
|
|
b58f9c6021 | ||
|
|
4560a72c32 | ||
|
|
85d375b128 | ||
|
|
99f49f9097 | ||
|
|
a0e6f7f022 | ||
|
|
1c3bbc9f6c | ||
|
|
07cb113c0a | ||
|
|
61a5cb44b8 | ||
|
|
6ccfd0101a | ||
|
|
1b29814e1e | ||
|
|
ae0e855d91 | ||
|
|
0aa4591021 | ||
|
|
c85295b5ea | ||
|
|
28213adfa6 | ||
|
|
11cab40103 | ||
|
|
41fd83e1d3 | ||
|
|
25b0b994a0 | ||
|
|
2b60f4496f | ||
|
|
1d714bfed7 | ||
|
|
b7d7bf7dd5 | ||
|
|
373af97472 | ||
|
|
3e9495a074 | ||
|
|
1072b71ea0 | ||
|
|
b0e3f11da1 | ||
|
|
cb0d6f40c9 | ||
|
|
0f69469eee | ||
|
|
f2a59c23f1 | ||
|
|
cac6f92964 | ||
|
|
0d2784a13e | ||
|
|
80a4c6ff14 | ||
|
|
013ae48221 | ||
|
|
daec3626bc | ||
|
|
fd695c9ad3 | ||
|
|
88ce04cea3 | ||
|
|
06d7a6d006 | ||
|
|
529fee1e20 | ||
|
|
ca9dfb7063 | ||
|
|
83ca45e0c8 | ||
|
|
fd411e200f | ||
|
|
3592a2ac17 | ||
|
|
8cc951202c | ||
|
|
ac89d1245b | ||
|
|
2172ec93a2 | ||
|
|
c173f28a3f | ||
|
|
a5a7329d41 | ||
|
|
ed10c1da67 | ||
|
|
bb730735f2 | ||
|
|
834b498aec | ||
|
|
2fb690b3b9 | ||
|
|
28a668ce09 | ||
|
|
5a2cf28c54 | ||
|
|
ed480e821c | ||
|
|
f11f7c5223 | ||
|
|
3b4bff79c2 | ||
|
|
f30dc5d186 | ||
|
|
da5c9dd424 | ||
|
|
89adfbc816 | ||
|
|
d125472e81 | ||
|
|
28495b9eb9 | ||
|
|
4fefa2ee28 | ||
|
|
00e93a5d30 | ||
|
|
95ef03baa8 | ||
|
|
dae3ebdb66 | ||
|
|
fb3e6ec1f4 | ||
|
|
bb4e4a9e53 | ||
|
|
4df27fc5b2 | ||
|
|
f7870310dc | ||
|
|
3c3fe46447 | ||
|
|
806f3a9bbf | ||
|
|
dca7cedb28 | ||
|
|
557342cc08 | ||
|
|
eb725a3a68 | ||
|
|
53f002c3f8 | ||
|
|
b48120947f | ||
|
|
4659289924 | ||
|
|
cc0ea22903 | ||
|
|
c0ca1a025b | ||
|
|
35b3a1f2a4 | ||
|
|
6731e44503 | ||
|
|
7b68e6e426 | ||
|
|
c36a96914b | ||
|
|
ab6f93db24 | ||
|
|
57079452b0 | ||
|
|
960bca7807 | ||
|
|
67400d1d72 | ||
|
|
ecfef570ea | ||
|
|
75875e244d | ||
|
|
1db33435c1 | ||
|
|
2d984da893 | ||
|
|
5b062a0d8d | ||
|
|
c0a7cf76b9 | ||
|
|
44e57aaaf5 | ||
|
|
d06fe5100e | ||
|
|
ae94302f4d | ||
|
|
b26b4435a5 | ||
|
|
da9a5f58d0 | ||
|
|
a4774ccc72 | ||
|
|
a6289f5e85 | ||
|
|
dd56e9a013 | ||
|
|
e31993bdf2 | ||
|
|
6dac633235 | ||
|
|
1d5300e02f | ||
|
|
b646365e2c | ||
|
|
798f3177f2 | ||
|
|
0921cf6e3b | ||
|
|
ac5f1998e4 | ||
|
|
433435889a | ||
|
|
a66afca68e | ||
|
|
b1213dcc59 | ||
|
|
f8c8c4040a | ||
|
|
2f33670b4f | ||
|
|
d8e10c41cf | ||
|
|
7e38ac68e3 | ||
|
|
abff805509 | ||
|
|
18072b3dd4 | ||
|
|
4640611758 | ||
|
|
baeda1998f | ||
|
|
e1a09551ce | ||
|
|
ba7a86de74 | ||
|
|
6cb79914a8 | ||
|
|
f1f0aa621a | ||
|
|
43a77d8699 | ||
|
|
58b88bf1fb | ||
|
|
96bc397821 | ||
|
|
fd508065dd | ||
|
|
416ef9e251 | ||
|
|
09250d0a92 | ||
|
|
822e06be39 | ||
|
|
c07ef75ac5 | ||
|
|
2a6f5d46ab | ||
|
|
e3f6a3327d | ||
|
|
6227aaee96 | ||
|
|
08591a8e8c | ||
|
|
106e023c80 | ||
|
|
a5de71933b | ||
|
|
e85888908a | ||
|
|
1a3b6d4cb3 | ||
|
|
e587ceb22e | ||
|
|
b769463d39 | ||
|
|
cbc88285d3 | ||
|
|
ec64820272 | ||
|
|
15b7ea6614 | ||
|
|
843555a4b1 | ||
|
|
5f4c26cb79 | ||
|
|
019042297d | ||
|
|
46a4469a9c | ||
|
|
646cb71a9d | ||
|
|
ad262172de | ||
|
|
343b70b19c | ||
|
|
b802e7e775 | ||
|
|
2cecd01b30 | ||
|
|
2ba1fc625f | ||
|
|
aff7a22ac5 | ||
|
|
5a23fd569b | ||
|
|
234e74202c | ||
|
|
914c874ada | ||
|
|
a6793b2695 | ||
|
|
cae5132038 | ||
|
|
45bf6a3862 | ||
|
|
f00a6a118d | ||
|
|
c599a59f05 | ||
|
|
c97a0684cf | ||
|
|
418413e334 | ||
|
|
815e0afdaf | ||
|
|
faf56680f8 | ||
|
|
b2d78dcca7 | ||
|
|
38e68eeb7a | ||
|
|
0f69cbf087 | ||
|
|
039080fc26 | ||
|
|
7e9cf858d6 | ||
|
|
a740af4afb | ||
|
|
a117b3cead | ||
|
|
e30efb716f | ||
|
|
43f5e4d2e0 | ||
|
|
e178bcc9f3 | ||
|
|
d8585d2ea3 | ||
|
|
96728e7ed9 | ||
|
|
83bdb6c347 | ||
|
|
085a6499a7 | ||
|
|
b371bd3d05 | ||
|
|
cf39677dfa | ||
|
|
a0bf57f529 | ||
|
|
7a10b700e2 | ||
|
|
aea84d8d79 | ||
|
|
e3f4c11500 | ||
|
|
e256a27b5a | ||
|
|
41c4c25315 | ||
|
|
9e56f750a7 | ||
|
|
4396196889 | ||
|
|
e6fe8436f4 | ||
|
|
f3f1c606b6 | ||
|
|
e9d3001dbf | ||
|
|
fd186eeb15 | ||
|
|
25607ceaee | ||
|
|
4b2c3e560b | ||
|
|
989016dff3 | ||
|
|
c54788fae4 | ||
|
|
c7fb2ad12c | ||
|
|
2fdeaf5599 | ||
|
|
1051e3f5a4 | ||
|
|
0b68c21840 | ||
|
|
ac26442ca6 | ||
|
|
b539e6dc46 | ||
|
|
06603a9c84 | ||
|
|
6b45f3ade5 | ||
|
|
6b246b2fed | ||
|
|
86f74e3da2 | ||
|
|
c4e7d7cb83 | ||
|
|
43b69a88a9 | ||
|
|
6d1da27b3c | ||
|
|
bae04005d3 | ||
|
|
edeca8c01b | ||
|
|
3aa35a77cb | ||
|
|
069e24bdb2 | ||
|
|
d0db0bab5c | ||
|
|
421f1b2c01 | ||
|
|
92027cc06f | ||
|
|
ddbeb212b7 | ||
|
|
d055944ebb | ||
|
|
40daa7195d | ||
|
|
3e8b39c404 | ||
|
|
e06201f042 | ||
|
|
2d7423100a | ||
|
|
6971d603d2 | ||
|
|
3af55796d9 | ||
|
|
200c1e788f | ||
|
|
aad9f4f0c1 | ||
|
|
d271fd6108 | ||
|
|
76625adec2 | ||
|
|
8b3f9f19f6 | ||
|
|
97f999ed9f | ||
|
|
e678a2c599 | ||
|
|
7e4b8aa49b | ||
|
|
c36f731316 | ||
|
|
849d3d3255 | ||
|
|
ec4cc14bf9 | ||
|
|
7de60867ef | ||
|
|
4011d54668 | ||
|
|
6056bc3b95 | ||
|
|
91f64c8662 | ||
|
|
274d0b522d | ||
|
|
ac7527fecf | ||
|
|
8bcbceef08 | ||
|
|
7ce9a969c8 | ||
|
|
f836e90869 | ||
|
|
6d07effbc3 | ||
|
|
a73b316681 | ||
|
|
70a2287568 | ||
|
|
9e3d8c9090 | ||
|
|
2d4c709a88 | ||
|
|
92ecff3fc0 | ||
|
|
2ed6b4e2f5 | ||
|
|
3761db65e0 | ||
|
|
eb006b3d39 | ||
|
|
f10f94bea3 | ||
|
|
710226c6db | ||
|
|
44a96df9fb | ||
|
|
cd788da47a | ||
|
|
c4eec78a02 | ||
|
|
1e33359d0c | ||
|
|
cf8357e004 | ||
|
|
8f243c01d5 | ||
|
|
e2aa68394c | ||
|
|
2828582c7a | ||
|
|
f6a2c635fd | ||
|
|
db24bf1d18 | ||
|
|
8c151a2d43 | ||
|
|
52cca1dd9b | ||
|
|
859f72eb84 | ||
|
|
b77d484a27 | ||
|
|
1733508e9a | ||
|
|
5f6c7743ad | ||
|
|
2550368d30 | ||
|
|
63aba1b3de | ||
|
|
42f79763e1 | ||
|
|
be19e91e91 | ||
|
|
9561aa767d | ||
|
|
4c629ec23f | ||
|
|
8864cd87ee | ||
|
|
f75428e52b | ||
|
|
b414aa755d | ||
|
|
5961800fe0 | ||
|
|
663af3dfb3 | ||
|
|
916f5b343a | ||
|
|
c0223977d1 | ||
|
|
e1c5d8950f | ||
|
|
20c46ca640 | ||
|
|
0aeb49d28a | ||
|
|
83d05f945f | ||
|
|
f0cae00574 | ||
|
|
46f7dff9e2 | ||
|
|
9ede4ba707 | ||
|
|
1c071530ad | ||
|
|
ba10671b2b | ||
|
|
188205399b | ||
|
|
af7134269e | ||
|
|
19a1afbd89 | ||
|
|
5359a762b8 | ||
|
|
0d0427f8bc | ||
|
|
0d6b8a86d4 | ||
|
|
6c01490372 | ||
|
|
4ab8520bfb | ||
|
|
d60a6cbc76 | ||
|
|
4bedc57b7d | ||
|
|
e1761d50a1 | ||
|
|
856368284e | ||
|
|
ad990994d0 | ||
|
|
247b5b6f0c | ||
|
|
6836947e67 | ||
|
|
dc873966e9 | ||
|
|
fe483e8e21 | ||
|
|
3a31577592 | ||
|
|
3721fc52a8 | ||
|
|
a7350282f0 | ||
|
|
c93ef97ab9 | ||
|
|
866e088f98 | ||
|
|
15ec0f8e2f | ||
|
|
fc14c2c01c | ||
|
|
71f8497ee6 | ||
|
|
5a0c0e2e97 | ||
|
|
3e079a47ae | ||
|
|
35c0cfcfea | ||
|
|
fa8deb524d | ||
|
|
f3773694bc | ||
|
|
1860742c13 | ||
|
|
f6d75e759c | ||
|
|
9b38b35420 | ||
|
|
b1afc3f34d | ||
|
|
1dfdabd638 | ||
|
|
f9512f55cc | ||
|
|
446b0b6429 | ||
|
|
cf4db99206 | ||
|
|
c854670062 | ||
|
|
e100565c67 | ||
|
|
f5d9e4bff4 | ||
|
|
7a7e1668fa | ||
|
|
4e13d6ae4d | ||
|
|
201d38c574 | ||
|
|
75a27e4cc7 | ||
|
|
95b07a2d23 | ||
|
|
94a710a5e1 | ||
|
|
b9dc9e81de | ||
|
|
1396fce961 | ||
|
|
884be64d17 | ||
|
|
8dbd685a90 | ||
|
|
4345e05e32 | ||
|
|
24b1a7735a | ||
|
|
168a7c4c45 | ||
|
|
a696aef959 | ||
|
|
6dddbde387 | ||
|
|
b9d92236e3 | ||
|
|
2dc14fc7e5 | ||
|
|
2908a74b42 | ||
|
|
1a41f13fd6 | ||
|
|
b16f3ff8e7 | ||
|
|
0f4aeede79 | ||
|
|
5d4873aa95 | ||
|
|
8ac337d515 | ||
|
|
2678068a86 | ||
|
|
64be5e2096 | ||
|
|
6b3d7759cc | ||
|
|
765b6c4015 | ||
|
|
1521d64784 | ||
|
|
25fbcea31a | ||
|
|
51e064d836 | ||
|
|
6ae7f67ef5 | ||
|
|
156a3c005d | ||
|
|
295337ac7e | ||
|
|
a39f51a571 | ||
|
|
d050c99161 | ||
|
|
1523cc0634 | ||
|
|
65d029279b | ||
|
|
d2d664a69b | ||
|
|
4a953b9d9d | ||
|
|
ae748cfffa | ||
|
|
ad215c5b4b | ||
|
|
2dd84e6de1 | ||
|
|
05d249d5ee | ||
|
|
f746ac8542 | ||
|
|
7af64df008 | ||
|
|
975ab3f4cc | ||
|
|
122ef1d862 | ||
|
|
4174ad844c | ||
|
|
41e65d9df1 | ||
|
|
2d0480c03d | ||
|
|
b0c9c8778d | ||
|
|
91c98f147f | ||
|
|
0bdeb00838 | ||
|
|
eee2184d10 | ||
|
|
df9801eac3 | ||
|
|
eacc9d8ce7 | ||
|
|
d6e7187d01 | ||
|
|
f61f045135 | ||
|
|
4668bc0ee3 | ||
|
|
ae93ee067c | ||
|
|
59165f077e | ||
|
|
832dbd644b | ||
|
|
00f8af0fb5 | ||
|
|
10ee9e5e99 | ||
|
|
33de1ffdc7 | ||
|
|
fe5663908c | ||
|
|
f23873e3f5 | ||
|
|
585bc329e6 | ||
|
|
c20e62d472 | ||
|
|
9260f9e0aa | ||
|
|
8532bf80df | ||
|
|
a2bb4099e6 | ||
|
|
182cbb1aa4 | ||
|
|
ccff331e3d | ||
|
|
43cc512e5a | ||
|
|
a265165038 | ||
|
|
8117a70608 | ||
|
|
dca12fcd7a | ||
|
|
e2dabe167d | ||
|
|
14a359679a | ||
|
|
3b111c794c | ||
|
|
1ca1934dbe | ||
|
|
ce8d333407 | ||
|
|
71e23c4e13 | ||
|
|
84776ca5f7 | ||
|
|
91acf877c6 | ||
|
|
0ebcf7e266 | ||
|
|
3c70a1b5a2 | ||
|
|
4effebb3ea | ||
|
|
9eff0d1cd8 | ||
|
|
07ddc9bf8a | ||
|
|
9048bcc6a0 | ||
|
|
94b2e0f1a3 | ||
|
|
a62b03743d | ||
|
|
4754935038 | ||
|
|
ee44433f86 | ||
|
|
9c8c8aee72 | ||
|
|
2739753f20 | ||
|
|
14de809fa5 | ||
|
|
06fa5b3b8f | ||
|
|
1b9ccf9cc6 | ||
|
|
36e825f093 | ||
|
|
13a53d077d | ||
|
|
479851e968 | ||
|
|
0867f72cb9 | ||
|
|
df08d0bd54 | ||
|
|
bb5c6437ff | ||
|
|
e1af20997d | ||
|
|
cd9f34076e | ||
|
|
0d897136c9 | ||
|
|
0e1b02e328 | ||
|
|
e3b5a14275 | ||
|
|
643bc92958 | ||
|
|
1c88c1e8d4 | ||
|
|
c3f051ac52 | ||
|
|
673c493694 | ||
|
|
4f3dac6477 | ||
|
|
d667e9d221 | ||
|
|
21e4427e57 | ||
|
|
7d29b40425 | ||
|
|
93055bc57c | ||
|
|
d5a3b81737 | ||
|
|
950ac3b993 | ||
|
|
beb496e3ed | ||
|
|
822435748a | ||
|
|
140904e201 | ||
|
|
25b4d9c34d | ||
|
|
a49e7e8295 | ||
|
|
542fa7e76d | ||
|
|
28f4092247 | ||
|
|
6adcdda06a | ||
|
|
d953d2b9fe | ||
|
|
7040084fbd | ||
|
|
6921d872a3 | ||
|
|
1544bd7b07 | ||
|
|
d28ac991ec | ||
|
|
9c90130fb3 | ||
|
|
765a97383a | ||
|
|
5cb287c3c7 | ||
|
|
32eebbbc0c | ||
|
|
a535b43290 | ||
|
|
63b1f6805a | ||
|
|
884e00ee8f | ||
|
|
f3d8d98807 | ||
|
|
4d8ae98621 | ||
|
|
e8a0413ad5 | ||
|
|
ff7e8ea315 | ||
|
|
91b997769e | ||
|
|
6654444e0f | ||
|
|
3561d9e063 | ||
|
|
c5c5b2a393 | ||
|
|
0c4c6cf199 | ||
|
|
a0583f6feb | ||
|
|
0673dd0b12 | ||
|
|
ef1242f234 | ||
|
|
f8c7485d82 | ||
|
|
88b54456ef | ||
|
|
2be298fc3f | ||
|
|
af812b0c55 | ||
|
|
09fb1e60e3 | ||
|
|
4575fec915 | ||
|
|
4c3db9e02f | ||
|
|
99f1d1bc7a | ||
|
|
ec5b10142f | ||
|
|
8d5dfa1ec2 | ||
|
|
27ef3a1d07 | ||
|
|
91f8b3060e | ||
|
|
86307c669f | ||
|
|
207ec2997f | ||
|
|
65c9b64f9a | ||
|
|
70162562b2 | ||
|
|
25a5623e77 | ||
|
|
4f386f19fe | ||
|
|
2be22d3bef | ||
|
|
0a9d8a6133 | ||
|
|
6a35a384b8 | ||
|
|
a8904b39ea | ||
|
|
08bd2ae669 | ||
|
|
65a0046891 | ||
|
|
421e1fc9f8 | ||
|
|
306405bcff | ||
|
|
7fb49693f4 | ||
|
|
19c3f9306f | ||
|
|
b056315410 | ||
|
|
691ce77800 | ||
|
|
966b4b11f6 | ||
|
|
b4de4c5ca1 | ||
|
|
0072a2ade5 | ||
|
|
eda752ab94 | ||
|
|
89206c51c3 | ||
|
|
21a172ca0d | ||
|
|
2e64db0261 | ||
|
|
b4b37b98aa | ||
|
|
dfb7c6731c | ||
|
|
2078e4a01a | ||
|
|
11c80b626c | ||
|
|
e3f63e09cf | ||
|
|
07efe31ff4 | ||
|
|
3837988f2d | ||
|
|
5ea142eaf0 | ||
|
|
38944883b1 | ||
|
|
ab6d69445e | ||
|
|
6c34280b66 | ||
|
|
279e594d3e | ||
|
|
a2c973bd5b | ||
|
|
96ba7df9d3 | ||
|
|
7e4e5b7271 | ||
|
|
1666c8cb4f | ||
|
|
1c9830b715 | ||
|
|
b10dece511 | ||
|
|
d8a37e8fd8 | ||
|
|
2ea96eaf83 | ||
|
|
a8a3c2a3c7 | ||
|
|
ab4d8c9165 | ||
|
|
8f19010b17 | ||
|
|
4fade082e5 | ||
|
|
2a78353ca4 | ||
|
|
efaf84f6f7 | ||
|
|
6f5b756786 | ||
|
|
bebe1f07df | ||
|
|
b23d945ed4 | ||
|
|
82ad0f0c5c | ||
|
|
f248d47a36 | ||
|
|
fa58aed475 | ||
|
|
4eb2340f2a | ||
|
|
474b8e0920 | ||
|
|
c77ab45dd3 | ||
|
|
76ae5934ba | ||
|
|
8233483477 | ||
|
|
10ca6d4215 | ||
|
|
2712f0aeaa | ||
|
|
aaa78ba949 | ||
|
|
080d06b838 | ||
|
|
00176b2c7e | ||
|
|
f2ff87f820 | ||
|
|
6a10f3e116 | ||
|
|
38ae98a565 | ||
|
|
f2be14868e | ||
|
|
e6829f6d4b | ||
|
|
469b676237 | ||
|
|
5e4456335a | ||
|
|
46376a4a11 | ||
|
|
72c79b58a8 | ||
|
|
de0d93c47e | ||
|
|
e6f89ad799 | ||
|
|
857ff5e8ed | ||
|
|
ee6c5e3399 | ||
|
|
5c7e9bb932 | ||
|
|
0f95c5b29b | ||
|
|
382f428a0e | ||
|
|
a91041bcf7 | ||
|
|
4fb0a5da21 | ||
|
|
f6b759dc71 | ||
|
|
6e1d53e11e | ||
|
|
7ac9388aed | ||
|
|
486197955b | ||
|
|
69e2f32984 | ||
|
|
5fe03c34f5 | ||
|
|
af312fd2ba | ||
|
|
ac52b502a2 | ||
|
|
f00d17b496 | ||
|
|
f252edb5c1 | ||
|
|
e45cd3c31c | ||
|
|
0f8513bf77 | ||
|
|
97392f4fdf | ||
|
|
74a0b0dab2 | ||
|
|
79329bdb45 | ||
|
|
d7940734b8 | ||
|
|
d9ebf93836 | ||
|
|
eda4ef8042 | ||
|
|
9b598ec306 | ||
|
|
93e8dd7a2c | ||
|
|
a78687ee5d | ||
|
|
a1db29b9a2 | ||
|
|
52644c2604 | ||
|
|
34b20b307b | ||
|
|
42c5794a05 | ||
|
|
d2a0fb8351 | ||
|
|
48914aaa7c | ||
|
|
8f0418d194 | ||
|
|
ecc23babc5 | ||
|
|
3f32911b90 | ||
|
|
6c1f784d25 | ||
|
|
18834904ef | ||
|
|
ba5663d3d3 | ||
|
|
d819aa0e4e | ||
|
|
ecb5637d9d | ||
|
|
b933e5e1ba | ||
|
|
d6db1ed511 | ||
|
|
eaeb362001 | ||
|
|
61bafdb37f | ||
|
|
a4ed5369c2 | ||
|
|
72988117d5 | ||
|
|
a760baa869 | ||
|
|
a026a5b61d | ||
|
|
25aadd4ae9 | ||
|
|
38a42fa954 | ||
|
|
e6f498a2da | ||
|
|
2500c65506 | ||
|
|
f387e1af37 | ||
|
|
2b9608d128 | ||
|
|
341e99587b | ||
|
|
9dd387b23e | ||
|
|
ceae45ed64 | ||
|
|
5f1b6bc281 | ||
|
|
33df0e6470 | ||
|
|
7aaa092efd | ||
|
|
232d22c148 | ||
|
|
9975036bb2 | ||
|
|
695c33147b | ||
|
|
6a96e07f18 | ||
|
|
bc994c60ee | ||
|
|
0c6d0d48a3 | ||
|
|
835ed44029 | ||
|
|
d1f1332555 | ||
|
|
27621e0945 | ||
|
|
d6b85d16cf | ||
|
|
64fdfbe13f | ||
|
|
18010c2eaa | ||
|
|
8e87fc4620 | ||
|
|
12919453d3 | ||
|
|
adbc158a5c | ||
|
|
69b14a6146 | ||
|
|
7d42f08431 | ||
|
|
95d5298ad9 | ||
|
|
1633b2e6db | ||
|
|
1e59100ff2 | ||
|
|
6337286959 | ||
|
|
ffa2970ae5 | ||
|
|
fdb85fd9bd | ||
|
|
c3361a67b2 | ||
|
|
a7c1d97164 | ||
|
|
aad8667a9f | ||
|
|
bdc98b4e1f | ||
|
|
a42629f947 | ||
|
|
4494fc8a5d | ||
|
|
41c435b808 | ||
|
|
929bbcaee4 | ||
|
|
013e6e9b21 | ||
|
|
c2404c307c | ||
|
|
5e9dd93e76 | ||
|
|
7260eb71f0 | ||
|
|
af5ed425c0 | ||
|
|
3c8c67a22e | ||
|
|
271ec3f6ee | ||
|
|
f7f675afd8 |
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@@ -1 +1 @@
|
||||
custom: ["https://littlevgl.com/donate"]
|
||||
custom: ["https://paypal.me/littlevgl?locale.x=en_US"]
|
||||
|
||||
14
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
14
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Documentation
|
||||
url: https://docs.lvgl.io
|
||||
about: Be sure to read to documentation first
|
||||
- name: Forum
|
||||
url: https://forum.lvgl.io
|
||||
about: For how-to questions use the forum
|
||||
- name: CONTIBUTING.md
|
||||
url: https://github.com/lvgl/lvgl/blob/master/docs/CONTRIBUTING.md#faq-about-contributing
|
||||
about: The basic rules of contributing
|
||||
- name: CODING_STYLE.md
|
||||
url: https://github.com/lvgl/lvgl/blob/master/docs/CODING_STYLE.md
|
||||
about: Quick summary of LVGL's code style
|
||||
12
.github/auto-comment.yml
vendored
Normal file
12
.github/auto-comment.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
# Comment to a new issue.
|
||||
pullRequestOpened: |
|
||||
Thank you for raising your pull request.
|
||||
|
||||
To ensure that all licensing criteria is met all repositories of the LVGL project apply a process called DCO (Developer's Certificate of Origin).
|
||||
|
||||
The text of DCO can be read here: https://developercertificate.org/
|
||||
For a more detailed description see the [Documentation](https://docs.lvgl.io/latest/en/html/contributing/index.html#developer-certification-of-origin-dco) site.
|
||||
|
||||
By contributing to any repositories of the LVGL project you state that your contribution corresponds with the DCO.
|
||||
|
||||
No further action is required if your contribution fulfills the DCO. If you are not sure about it feel free to ask us in a comment.
|
||||
6
.github/workflows/ccpp.yml
vendored
6
.github/workflows/ccpp.yml
vendored
@@ -2,9 +2,9 @@ name: C/C++ CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ dev-7.0 ]
|
||||
branches: [ master, dev ]
|
||||
pull_request:
|
||||
branches: [ dev-7.0 ]
|
||||
branches: [master, dev ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -14,4 +14,4 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Run tests
|
||||
run: cd tests; python ./build.py
|
||||
run: sudo apt-get install libpng-dev; cd tests; python ./build.py
|
||||
|
||||
17
.github/workflows/merge-to-dev.yml
vendored
Normal file
17
.github/workflows/merge-to-dev.yml
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
name: Merge master branch to dev
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
jobs:
|
||||
merge-branch:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: Merge to dev branch
|
||||
uses: devmasx/merge-branch@v1.1.0
|
||||
with:
|
||||
type: now
|
||||
target_branch: 'dev'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||
155
CHANGELOG.md
155
CHANGELOG.md
@@ -1,13 +1,162 @@
|
||||
# Changelog
|
||||
|
||||
## v7.0.0 - under development
|
||||
To try the new version use the `dev-7.0` branch of LVGL and the [Simulator](https://github.com/littlevgl/lv_sim_eclipse_sdl/tree/dev-7.0).
|
||||
## v7.4.0 (01.09.2020)
|
||||
|
||||
The main new features of v7.4 are run-time font loading, style caching and arc knob with value setting by click.
|
||||
|
||||
### New features
|
||||
- Add `lv_font_load()` function - Loads a `lv_font_t` object from a binary font file
|
||||
- Add `lv_font_free()` function - Frees the memory allocated by the `lv_font_load()` function
|
||||
- Add style caching to reduce acces time of properties with default value
|
||||
- arc: add set value by click feature
|
||||
- arc: add `LV_ARC_PART_KNOB` similarly to slider
|
||||
- send gestures even is the the obejct was dragged. User can check dragging with `lv_indev_is_dragging(lv_indev_act())` in the event function.
|
||||
|
||||
### Bugfixes
|
||||
- Fix color bleeding on border drawing
|
||||
- Fix using 'LV_SCROLLBAR_UNHIDE' after 'LV_SCROLLBAR_ON'
|
||||
- Fix croping of last column/row if an image is zoomed
|
||||
- Fix zooming and rotateing mosaic images
|
||||
- Fix deleting tabview with LEFT/RIGHT tab position
|
||||
- Fix btnmatrix to not send event when CLICK_TRIG = true and the cursor slid from a pressed button
|
||||
- Fix roller width if selected text is larger than the normal
|
||||
|
||||
## v7.3.1 (18.08.2020)
|
||||
|
||||
### Bugfixes
|
||||
- Fix drawing value string twice
|
||||
- Rename `lv_chart_clear_serie` to `lv_chart_clear_series` and `lv_obj_align_origo` to `lv_obj_align_mid`
|
||||
- Add linemeter's mirror feature again
|
||||
- Fix text decor (udnerline strikethrough) with older versions of font converter
|
||||
- Fix setting local style property multiple times
|
||||
- Add missing background drawing and radius handling to image button
|
||||
- Allow adding extra label to list buttons
|
||||
- Fix crash if `lv_table_set_col_cnt` is called before `lv_table_set_row_cnt` for the first time
|
||||
- Fix overflow in large image transformations
|
||||
- Limit extra button click area of button matrix's buttons. With large paddings it was counter intuitive. (Gaps are mapped to button when clicked).
|
||||
- Fix `lv_btnmatrix_set_one_check` not forcing exactly one button to be checked
|
||||
- Fix color picker invalidation in rectangle mode
|
||||
- Init disabled days to gray color in calendar
|
||||
|
||||
## v7.3.0 (04.08.2020)
|
||||
|
||||
### New features
|
||||
- Add `lv_task_get_next`
|
||||
- Add `lv_event_send_refresh`, `lv_event_send_refresh_recursive` to easily send `LV_EVENT_REFRESH` to object
|
||||
- Add `lv_tabview_set_tab_name()` function - used to change a tab's name
|
||||
- Add `LV_THEME_MATERIAL_FLAG_NO_TRANSITION` and `LV_THEME_MATERIAL_FLAG_NO_FOCUS` flags
|
||||
- Reduce code size by adding: `LV_USE_FONT_COMPRESSED` and `LV_FONT_USE_SUBPX` and applying some optimization
|
||||
- Add `LV_MEMCPY_MEMSET_STD` to use standard `memcpy` and `memset`
|
||||
|
||||
### Bugfixes
|
||||
- Do not print warning for missing glyph if its height OR width is zero.
|
||||
- Prevent duplicated sending of `LV_EVENT_INSERT` from text area
|
||||
- Tidy outer edges of cpicker widget.
|
||||
- Remove duplicated lines from `lv_tabview_add_tab`
|
||||
- btnmatrix: hadle combined states of buttons (e.g. chacked + disabled)
|
||||
- textarea: fix typo in lv_textarea_set_sscrollbar_mode
|
||||
- gauge: fix image needle drawing
|
||||
- fix using freed memory in _lv_style_list_remove_style
|
||||
|
||||
|
||||
## v7.2.0 (21.07.2020)
|
||||
|
||||
### New features
|
||||
- Add screen transitions with `lv_scr_load_anim()`
|
||||
- Add display background color, wallpaper and opacity. Shown when the screen is transparent. Can be used with `lv_disp_set_bg_opa/color/image()`.
|
||||
- Add `LV_CALENDAR_WEEK_STARTS_MONDAY`
|
||||
- Add `lv_chart_set_x_start_point()` function - Set the index of the x-axis start point in the data array
|
||||
- Add `lv_chart_set_ext_array()` function - Set an external array of data points to use for the chart
|
||||
- Add `lv_chart_set_point_id()` function - Set an individual point value in the chart series directly based on index
|
||||
- Add `lv_chart_get_x_start_point()` function - Get the current index of the x-axis start point in the data array
|
||||
- Add `lv_chart_get_point_id()` function - Get an individual point value in the chart series directly based on index
|
||||
- Add `ext_buf_assigned` bit field to `lv_chart_series_t` structure - it's true if external buffer is assigned to series
|
||||
- Add `lv_chart_set_series_axis()` to assign series to primary or secondary axis
|
||||
- Add `lv_chart_set_y_range()` to allow setting range of secondary y axis (based on `lv_chart_set_range` but extended with an axis parameter)
|
||||
- Allow setting different font for the selected text in `lv_roller`
|
||||
- Add `theme->apply_cb` to replace `theme->apply_xcb` to make it compatible with the MicroPython binding
|
||||
- Add `lv_theme_set_base()` to allow easy extension of built-in (or any) themes
|
||||
- Add `lv_obj_align_x()` and `lv_obj_align_y()` functions
|
||||
- Add `lv_obj_align_origo_x()` and `lv_obj_align_origo_y()` functions
|
||||
|
||||
### Bugfixes
|
||||
- `tileview` fix navigation when not screen sized
|
||||
- Use 14px font by default to for better compatibility with smaller displays
|
||||
- `linemeter` fix conversation of current value to "level"
|
||||
- Fix drawing on right border
|
||||
- Set the cursor image non clickable by default
|
||||
- Improve mono theme when used with keyboard or encoder
|
||||
|
||||
## v7.1.0 (07.07.2020)
|
||||
|
||||
### New features
|
||||
- Add `focus_parent` attribute to `lv_obj`
|
||||
- Allow using buttons in encoder input device
|
||||
- Add lv_btnmatrix_set/get_align capability
|
||||
- DMA2D: Remove dependency on ST CubeMX HAL
|
||||
- Added `max_used` propriety to `lv_mem_monitor_t` struct
|
||||
- In `lv_init` test if the the strings are UTF-8 encoded.
|
||||
- Add `user_data` to themes
|
||||
- Add LV_BIG_ENDIAN_SYSTEM flag to lv_conf.h in order to fix displaying images on big endian systems.
|
||||
- Add inline function lv_checkbox_get_state(const lv_obj_t * cb) to extend the checkbox functionality.
|
||||
- Add inline function lv_checkbox_set_state(const lv_obj_t * cb, lv_btn_state_t state ) to extend the checkbox functionality.
|
||||
|
||||
### Bugfixes
|
||||
- `lv_img` fix invalidation area when angle or zoom changes
|
||||
- Update the style handling to support Big endian MCUs
|
||||
- Change some methods to support big endian hardware.
|
||||
- remove use of c++ keyword 'new' in parameter of function lv_theme_set_base().
|
||||
- Add LV_BIG_ENDIAN_SYSTEM flag to lv_conf.h in order to fix displaying images on big endian systems.
|
||||
- Fix inserting chars in text area in big endian hardware.
|
||||
|
||||
## v7.0.2 (16.06.2020)
|
||||
|
||||
### Bugfixes
|
||||
- `lv_textarea` fix wrong cursor position when clicked after the last character
|
||||
- Change all text related indices from 16-bit to 32-bit integers throughout whole library. #1545
|
||||
- Fix gestures
|
||||
- Do not call `set_px_cb` for transparent pixel
|
||||
- Fix list button focus in material theme
|
||||
- Fix crash when the a text area is cleared with the backspace of a keyboard
|
||||
- Add version number to `lv_conf_template.h`
|
||||
- Add log in true double buffering mode with `set_px_cb`
|
||||
- `lv_dropdown`: fix missing `LV_EVENT_VALUE_CHANGED` event when used with encoder
|
||||
- `lv_tileview`: fix if not the {0;0} tile is created first
|
||||
- `lv_debug`: restructure to allow asserting in from `lv_misc` too
|
||||
- add assert if `_lv_mem_buf_get()` fails
|
||||
- `lv_textarea`: fix character delete in password mode
|
||||
- Update `LV_OPA_MIN` and `LV_OPA_MAX` to widen the opacity processed range
|
||||
- `lv_btnm` fix sending events for hidden buttons
|
||||
- `lv_gaguge` make `lv_gauge_set_angle_offset` offset the labels and needles too
|
||||
- Fix typo in the API `scrllable` -> `scrollable`
|
||||
- `tabview` by default allow auto expanding the page only to right and bottom (#1573)
|
||||
- fix crash when drawing gradient to the same color
|
||||
- chart: fix memory leak
|
||||
- `img`: improve hit test for transformed images
|
||||
|
||||
## v7.0.1 (01.06.2020)
|
||||
|
||||
### Bugfixes
|
||||
- Make the Microptyhon working by adding the required variables as GC_ROOT
|
||||
- Prefix some internal API functions with `_` to reduce the API of LVGL
|
||||
- Fix built-in SimSun CJK font
|
||||
- Fix UTF-8 encoding when `LV_USE_ARABIC_PERSIAN_CHARS` is enabled
|
||||
- Fix DMA2D usage when 32 bit images directly blended
|
||||
- Fix lv_roller in infinite mode when used with encoder
|
||||
- Add `lv_theme_get_color_secondary()`
|
||||
- Add `LV_COLOR_MIX_ROUND_OFS` to adjust color mixing to make it compatible with the GPU
|
||||
- Improve DMA2D blending
|
||||
- Remove memcpy from `lv_ll` (caused issues with some optimization settings)
|
||||
- `lv_chart` fix X tick drawing
|
||||
- Fix vertical dashed line drawing
|
||||
- Some additonal minor fixes and formattings
|
||||
|
||||
## v7.0.0 (18.05.2020)
|
||||
|
||||
### Documentation
|
||||
The docs for v7 is available at https://docs.littlevgl.com/v7/en/html/index.html
|
||||
|
||||
### Legal changes
|
||||
*In progress*
|
||||
|
||||
The name of the project is changed to LVGL and the new website is on https://lvgl.io
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
MIT licence
|
||||
Copyright (c) 2016 Gábor Kiss-Vámosi
|
||||
Copyright (c) 2020 LVGL LLC
|
||||
|
||||
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:
|
||||
|
||||
|
||||
448
README.md
448
README.md
@@ -1,235 +1,124 @@
|
||||
<h1 align="center"> LittlevGL - Open-source Embedded GUI Library</h1>
|
||||
<h1 align="center"> LVGL - Light and Versatile Graphics Library</h1>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/littlevgl/lvgl/blob/master/LICENCE.txt"><img src="https://img.shields.io/badge/licence-MIT-blue.svg"></a>
|
||||
<a href="https://github.com/littlevgl/lvgl/releases/tag/v6.1.2"><img src="https://img.shields.io/badge/version-6.1.2-blue.svg"></a>
|
||||
<img src="https://lvgl.io/assets/images/img_1.png">
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<img src="https://littlevgl.com/github/cover_ori_reduced_2.gif">
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
LittlevGL provides everything you need to create a Graphical User Interface (GUI) on embedded systems with easy-to-use graphical elements, beautiful visual effects and low memory footprint.
|
||||
LVGL provides everything you need to create embedded GUI with easy-to-use graphical elements, beautiful visual effects and low memory footprint.
|
||||
</p>
|
||||
|
||||
<h4 align="center">
|
||||
<a href="https://littlevgl.com">Website </a> ·
|
||||
<a href="https://littlevgl.com/live-demo">Live demo</a> ·
|
||||
<a href="https://docs.littlevgl.com/en/html/get-started/pc-simulator.html">Simulator</a> ·
|
||||
<a href="https://forum.littlevgl.com">Forum</a> ·
|
||||
<a href="https://docs.littlevgl.com/">Docs</a> ·
|
||||
<a href="https://blog.littlevgl.com/">Blog</a>
|
||||
<a href="https://lvgl.io">Website </a> ·
|
||||
<a href="https://lvgl.io/demos">Online demo</a> ·
|
||||
<a href="https://docs.lvgl.io/">Docs</a> ·
|
||||
<a href="https://forum.lvgl.io">Forum</a>
|
||||
</h4>
|
||||
|
||||
---
|
||||
|
||||
- [Features](#features)
|
||||
- [Supported devices](#supported-devices)
|
||||
- [Quick start in a simulator](#quick-start-in-a-simulator)
|
||||
- [Add LittlevGL to your project](#add-littlevgl-to-your-project)
|
||||
- [Learn the basics](#learn-the-basics)
|
||||
- [Examples](#examples)
|
||||
- [Contributing](#contributing)
|
||||
- [Donate](#donate)
|
||||
|
||||
|
||||
## Features
|
||||
* **Powerful building blocks** buttons, charts, lists, sliders, images, etc.
|
||||
* **Advanced graphics** with animations, anti-aliasing, opacity, smooth scrolling
|
||||
* **Simultaneously use various input devices** touchscreen, mouse, keyboard, encoder, buttons, etc.
|
||||
* **Simultaneously use multiple displays** i.e. monochrome and color display
|
||||
* **Multi-language support** with UTF-8 encoding
|
||||
* **Fully customizable** graphical elements
|
||||
* **Hardware independent** to use with any microcontroller or display
|
||||
* **Scalable** to operate with little memory (64 kB Flash, 10 kB RAM)
|
||||
* **OS, External memory and GPU** supported but not required
|
||||
* **Single frame buffer** operation even with advances graphical effects
|
||||
* **Written in C** for maximal compatibility
|
||||
* **Micropython Binding** exposes [LittlevGL API in Micropython](https://blog.littlevgl.com/2019-02-20/micropython-bindings)
|
||||
* **Simulator** to develop on PC without embedded hardware
|
||||
* **Tutorials, examples, themes** for rapid development
|
||||
* **Documentation** and API references
|
||||
* Powerful [building blocks](https://docs.lvgl.io/latest/en/html/widgets/index.html): buttons, charts, lists, sliders, images, etc.
|
||||
* Advanced graphics: animations, anti-aliasing, opacity, smooth scrolling
|
||||
* Use [various input devices](https://docs.lvgl.io/latest/en/html/overview/indev.html): touchscreen, mouse, keyboard, encoder, buttons, etc.
|
||||
* Use [multiple displays](https://docs.lvgl.io/latest/en/html/overview/display.html): e.g. monochrome and color display
|
||||
* Hardware independent to use with any microcontroller or display
|
||||
* Scalable to operate with little memory (64 kB Flash, 10 kB RAM)
|
||||
* Multi-language support with UTF-8 handling, Bidirectional and Arabic script support
|
||||
* Fully customizable graphical elements via [CSS-like styles](https://docs.lvgl.io/latest/en/html/overview/style.html)
|
||||
* OS, External memory and GPU are supported but not required
|
||||
* Smooth rendering even with a [single frame buffer](https://docs.lvgl.io/latest/en/html/porting/display.html)
|
||||
* Written in C for maximal compatibility (C++ compatible)
|
||||
* Micropython Binding exposes [LVGL API in Micropython](https://blog.lvgl.io/2019-02-20/micropython-bindings)
|
||||
* [Simulator](https://docs.lvgl.io/latest/en/html/get-started/pc-simulator.html) to develop on PC without embedded hardware
|
||||
* [Examples](lv_examples) and tutorials for rapid development
|
||||
* [Documentation](http://docs.lvgl.io/) and API references
|
||||
|
||||
## Supported devices
|
||||
Basically, every modern controller - which is able to drive a display - is suitable to run LittlevGL. The minimal requirements:
|
||||
- 16, 32 or 64 bit microcontroller or processor
|
||||
- > 16 MHz clock speed is recommended
|
||||
- Flash/ROM: > 64 kB for the very essential components (> 180 kB is recommended)
|
||||
- RAM:
|
||||
- Static RAM usage: ~8..16 kB depending on the used features and objects types
|
||||
- Stack: > 2kB (> 4 kB is recommended)
|
||||
- Dynamic data (heap): > 4 KB (> 16 kB is recommended if using several objects).
|
||||
Set by `LV_MEM_SIZE` in *lv_conf.h*.
|
||||
- Display buffer: > *"Horizontal resolution"* pixels (> 10 × *"Horizontal resolution"* is recommended)
|
||||
- C99 or newer compiler
|
||||
## Requirements
|
||||
Basically, every modern controller (which is able to drive a display) is suitable to run LVGL. The minimal requirements are:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td> <strong>Name</strong> </td>
|
||||
<td><strong>Minimal</strong></td>
|
||||
<td><strong>Recommended</strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Architecture</strong></td>
|
||||
<td colspan="2">16, 32 or 64 bit microcontroller or processor</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> <strong>Clock</strong></td>
|
||||
<td> > 16 MHz </td>
|
||||
<td> > 48 MHz</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> <strong>Flash/ROM</strong></td>
|
||||
<td> > 64 kB </td>
|
||||
<td> > 180 kB</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> <strong>Static RAM</strong></td>
|
||||
<td> > 2 kB </td>
|
||||
<td> > 4 kB</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> <strong>Stack</strong></td>
|
||||
<td> > 2 kB </td>
|
||||
<td> > 8 kB</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> <strong>Heap</strong></td>
|
||||
<td> > 2 kB </td>
|
||||
<td> > 8 kB</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> <strong>Display buffer</strong></td>
|
||||
<td> > 1 × <em>hor. res.</em> pixels </td>
|
||||
<td> > 10 × <em>hor. res.</em> pixels </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> <strong>Compiler</strong></td>
|
||||
<td colspan="2"> C99 or newer </td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
*Note that the memory usage might vary depending on the architecture, compiler and build options.*
|
||||
|
||||
Just to mention some **platforms**:
|
||||
- STM32F1, STM32F3, [STM32F4](https://blog.littlevgl.com/2017-07-15/stm32f429_disco_port), [STM32F7](https://github.com/littlevgl/stm32f746_disco_no_os_sw4stm32)
|
||||
Just to mention some platforms:
|
||||
- STM32F1, STM32F3, STM32F4, STM32F7, STM32L4, STM32L5, STM32H7
|
||||
- Microchip dsPIC33, PIC24, PIC32MX, PIC32MZ
|
||||
- NXP Kinetis, LPC, iMX
|
||||
- [Linux frame buffer](https://blog.littlevgl.com/2018-01-03/linux_fb) (/dev/fb)
|
||||
- [Raspberry PI](http://www.vk3erw.com/index.php/16-software/63-raspberry-pi-official-7-touchscreen-and-littlevgl)
|
||||
- [Espressif ESP32](https://github.com/littlevgl/lv_port_esp32)
|
||||
- Nordic nrf52
|
||||
- Quectell M66
|
||||
|
||||
## Quick start in a simulator
|
||||
The easiest way to get started with LittlevGL is to run it in a simulator on your PC without any embedded hardware.
|
||||
|
||||
Choose a project with your favourite IDE:
|
||||
|
||||
| Eclipse | CodeBlocks | Visual Studio | PlatformIO | Qt Creator |
|
||||
|-------------|-------------|---------------|-----------|------------|
|
||||
| [](https://github.com/littlevgl/pc_simulator_sdl_eclipse) | [](https://github.com/littlevgl/pc_simulator_win_codeblocks) | [](https://github.com/littlevgl/visual_studio_2017_sdl_x64) | [](https://github.com/littlevgl/pc_simulator_sdl_platformio) | [](https://blog.littlevgl.com/2019-01-03/qt-creator) |
|
||||
| Cross-platform<br>with SDL<br>(Recommended on<br>Linux and Mac) | Native Windows | Windows<br>with SDL | Cross-platform<br>with SDL | Cross-platform<br>with SDL |
|
||||
|
||||
|
||||
## Add LittlevGL to your project
|
||||
|
||||
The steps below show how to setup LittlevGL on an embedded system with a display and a touchpad.
|
||||
You can use the [Simulators](https://docs.littlevgl.com/en/html/get-started/pc-simulator) to get ready to use projects which can be run on your PC.
|
||||
|
||||
1. [Download](https://littlevgl.com/download) or [Clone](https://github.com/littlevgl/lvgl) the library
|
||||
2. Copy the `lvgl` folder into your project
|
||||
3. Copy `lvgl/lv_conf_template.h` as `lv_conf.h` next to the `lvgl` folder and set at least `LV_HOR_RES_MAX`, `LV_VER_RES_MAX` and `LV_COLOR_DEPTH`. Don't forget to **change the `#if 0` statement near the top of the file to `#if 1`**, otherwise you will get compilation errors.
|
||||
4. Include `lvgl/lvgl.h` where you need to use LittlevGL related functions.
|
||||
5. Call `lv_tick_inc(x)` every `x` milliseconds **in a Timer or Task** (`x` should be between 1 and 10). It is required for the internal timing of LittlevGL.
|
||||
6. Call `lv_init()`
|
||||
7. Create a display buffer for LittlevGL
|
||||
```c
|
||||
static lv_disp_buf_t disp_buf;
|
||||
static lv_color_t buf[LV_HOR_RES_MAX * 10]; /*Declare a buffer for 10 lines*/
|
||||
lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10); /*Initialize the display buffer*/
|
||||
```
|
||||
8. Implement and register a function which can **copy a pixel array** to an area of your display:
|
||||
```c
|
||||
lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
|
||||
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
|
||||
disp_drv.flush_cb = my_disp_flush; /*Set your driver function*/
|
||||
disp_drv.buffer = &disp_buf; /*Assign the buffer to the display*/
|
||||
lv_disp_drv_register(&disp_drv); /*Finally register the driver*/
|
||||
|
||||
void my_disp_flush(lv_disp_t * disp, const lv_area_t * area, lv_color_t * color_p)
|
||||
{
|
||||
int32_t x, y;
|
||||
for(y = area->y1; y <= area->y2; y++) {
|
||||
for(x = area->x1; x <= area->x2; x++) {
|
||||
set_pixel(x, y, *color_p); /* Put a pixel to the display.*/
|
||||
color_p++;
|
||||
}
|
||||
}
|
||||
|
||||
lv_disp_flush_ready(disp); /* Indicate you are ready with the flushing*/
|
||||
}
|
||||
|
||||
```
|
||||
9. Implement and register a function which can **read an input device**. E.g. for a touch pad:
|
||||
```c
|
||||
lv_indev_drv_init(&indev_drv); /*Descriptor of a input device driver*/
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER; /*Touch pad is a pointer-like device*/
|
||||
indev_drv.read_cb = my_touchpad_read; /*Set your driver function*/
|
||||
lv_indev_drv_register(&indev_drv); /*Finally register the driver*/
|
||||
|
||||
bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
|
||||
{
|
||||
static lv_coord_t last_x = 0;
|
||||
static lv_coord_t last_y = 0;
|
||||
|
||||
/*Save the state and save the pressed coordinate*/
|
||||
data->state = touchpad_is_pressed() ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
|
||||
if(data->state == LV_INDEV_STATE_PR) touchpad_get_xy(&last_x, &last_y);
|
||||
|
||||
/*Set the coordinates (if released use the last pressed coordinates)*/
|
||||
data->point.x = last_x;
|
||||
data->point.y = last_y;
|
||||
|
||||
return false; /*Return `false` because we are not buffering and no more data to read*/
|
||||
}
|
||||
```
|
||||
10. Call `lv_task_handler()` periodically every few milliseconds in the main `while(1)` loop, in Timer interrupt or in an Operation system task.
|
||||
It will redraw the screen if required, handle input devices etc.
|
||||
|
||||
|
||||
## Learn the basics
|
||||
|
||||
### Objects (Widgets)
|
||||
|
||||
The graphical elements like Buttons, Labels, Sliders, Charts etc are called objects in LittelvGL. Go to [Object types](https://docs.littlevgl.com/en/html/object-types/index) to see the full list of available types.
|
||||
|
||||
Every object has a parent object. The child object moves with the parent and if you delete the parent the children will be deleted too. Children can be visible only on their parent.
|
||||
|
||||
The *screen* are the "root" parents. To get the current screen call `lv_scr_act()`.
|
||||
|
||||
You can create a new object with `lv_<type>_create(parent, obj_to_copy)`. It will return an `lv_obj_t *` variable which should be used as a reference to the object to set its parameters.
|
||||
The first parameter is the desired *parent*, te second parameters can be an object to copy (`NULL` is unused).
|
||||
For example:
|
||||
```c
|
||||
lv_obj_t * slider1 = lv_slider_create(lv_scr_act(), NULL);
|
||||
```
|
||||
|
||||
To set some basic attribute `lv_obj_set_<paramters_name>(obj, <value>)` function can be used. For example:
|
||||
```c
|
||||
lv_obj_set_x(btn1, 30);
|
||||
lv_obj_set_y(btn1, 10);
|
||||
lv_obj_set_size(btn1, 200, 50);
|
||||
```
|
||||
|
||||
The objects has type specific parameters too which can be set by `lv_<type>_set_<paramters_name>(obj, <value>)` functions. For example:
|
||||
```c
|
||||
lv_slider_set_value(slider1, 70, LV_ANIM_ON);
|
||||
```
|
||||
|
||||
To see the full API visit the documentation of the object types or the related header file (e.g. `lvgl/src/lv_objx/lv_slider.h`).
|
||||
|
||||
### Styles
|
||||
Styles can be assigned to the objects to changed their appearance. A style describes the appearance of rectangle-like objects (like a button or slider), texts, images and lines at once.
|
||||
|
||||
You can create a new style like this:
|
||||
```c
|
||||
static lv_style_t style1; /*Declare a new style. Should be `static`*/
|
||||
lv_style_copy(&style1, &lv_style_plain); /*Copy a built-in style*/
|
||||
style1.body.main_color = LV_COLOR_RED; /*Main color*/
|
||||
style1.body.grad_color = lv_color_hex(0xffd83c) /*Gradient color (orange)*/
|
||||
style1.body.radius = 3;
|
||||
style1.text.color = lv_color_hex3(0x0F0) /*Label color (green)*/
|
||||
style1.text.font = &lv_font_dejavu_22; /*Change font*/
|
||||
...
|
||||
```
|
||||
|
||||
To set a new style for an object use the `lv_<type>set_style(obj, LV_<TYPE>_STYLE_<NAME>, &my_style)` functions. For example:
|
||||
```c
|
||||
lv_slider_set_style(slider1, LV_SLIDER_STYLE_BG, &slider_bg_style);
|
||||
lv_slider_set_style(slider1, LV_SLIDER_STYLE_INDIC, &slider_indic_style);
|
||||
lv_slider_set_style(slider1, LV_SLIDER_STYLE_KNOB, &slider_knob_style);
|
||||
```
|
||||
|
||||
If an object's style is `NULL` then it will inherit its parent's style. For example, the labels' style are `NULL` by default. If you place them on a button then they will use the `style.text` properties from the button's style.
|
||||
|
||||
Learn more in [Style overview](https://docs.littlevgl.com/en/html/overview/style) section.
|
||||
|
||||
### Events
|
||||
Events are used to inform the user if something has happened with an object. You can assign a callback to an object which will be called if the object is clicked, released, dragged, being deleted etc. It should look like this:
|
||||
|
||||
```c
|
||||
lv_obj_set_event_cb(btn, btn_event_cb); /*Assign a callback to the button*/
|
||||
|
||||
...
|
||||
|
||||
void btn_event_cb(lv_obj_t * btn, lv_event_t event)
|
||||
{
|
||||
if(event == LV_EVENT_CLICKED) {
|
||||
printf("Clicked\n");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Learn more about the events in the [Event overview](https://docs.littlevgl.com/en/html/overview/event) section.
|
||||
- NXP: Kinetis, LPC, iMX, iMX RT
|
||||
- [Linux frame buffer](https://blog.lvgl.io/2018-01-03/linux_fb) (/dev/fb)
|
||||
- [Raspberry Pi](http://www.vk3erw.com/index.php/16-software/63-raspberry-pi-official-7-touchscreen-and-littlevgl)
|
||||
- [Espressif ESP32](https://github.com/lvgl/lv_port_esp32)
|
||||
- [Infineon Aurix](https://github.com/lvgl/lv_port_aurix)
|
||||
- Nordic NRF52 Bluetooth modules
|
||||
- Quectel modems
|
||||
|
||||
## Get started
|
||||
This list shows the recommended way of learning the library:
|
||||
1. Check the [Online demos](https://lvgl.io/demos) to see LVGL in action (3 minutes)
|
||||
2. Read the [Introduction](https://docs.lvgl.io/latest/en/html/intro/index.html) page of the documentation (5 minutes)
|
||||
3. Get familiar with the basics on the [Quick overview](https://docs.lvgl.io/latest/en/html/get-started/quick-overview.html) page (15 minutes)
|
||||
4. Set up a [Simulator](https://docs.lvgl.io/latest/en/html/get-started/pc-simulator.html) (10 minutes)
|
||||
5. Try out some [Examples](https://github.com/lvgl/lv_examples/)
|
||||
6. Port LVGL to a board. See the [Porting](https://docs.lvgl.io/latest/en/html/porting/index.html) guide or check the ready to use [Projects](https://github.com/lvgl?q=lv_port_&type=&language=)
|
||||
7. Read the [Overview](https://docs.lvgl.io/latest/en/html/overview/index.html) page to get a better understanding of the library (2-3 hours)
|
||||
8. Check the documentation of the [Widgets](https://docs.lvgl.io/latest/en/html/widgets/index.html) to see their features and usage
|
||||
9. If you have questions go to the [Forum](http://forum.lvgl.io/)
|
||||
10. Read the [Contributing](https://docs.lvgl.io/latest/en/html/contributing/index.html) guide to see how you can help to improve LVGL (15 minutes)
|
||||
|
||||
## Examples
|
||||
|
||||
For more examples see the [lv_examples](https://github.com/lvgl/lv_examples) repository.
|
||||
|
||||
### Button with label
|
||||
```c
|
||||
lv_obj_t * btn = lv_btn_create(lv_scr_act(), NULL); /*Add a button the current screen*/
|
||||
@@ -249,121 +138,10 @@ void btn_event_cb(lv_obj_t * btn, lv_event_t event)
|
||||
}
|
||||
}
|
||||
```
|
||||

|
||||

|
||||
|
||||
### Button with styles
|
||||
Add styles to the previously button from the previous example
|
||||
```c
|
||||
static lv_style_t style_btn_rel; /*A variable to store the released style*/
|
||||
lv_style_copy(&style_btn_rel, &lv_style_plain); /*Initialize from a built-in style*/
|
||||
style_btn_rel.body.border.color = lv_color_hex3(0x269);
|
||||
style_btn_rel.body.border.width = 1;
|
||||
style_btn_rel.body.main_color = lv_color_hex3(0xADF);
|
||||
style_btn_rel.body.grad_color = lv_color_hex3(0x46B);
|
||||
style_btn_rel.body.shadow.width = 4;
|
||||
style_btn_rel.body.shadow.type = LV_SHADOW_BOTTOM;
|
||||
style_btn_rel.body.radius = LV_RADIUS_CIRCLE;
|
||||
style_btn_rel.text.color = lv_color_hex3(0xDEF);
|
||||
|
||||
static lv_style_t style_btn_pr; /*A variable to store the pressed style*/
|
||||
lv_style_copy(&style_btn_pr, &style_btn_rel); /*Initialize from the released style*/
|
||||
style_btn_pr.body.border.color = lv_color_hex3(0x46B);
|
||||
style_btn_pr.body.main_color = lv_color_hex3(0x8BD);
|
||||
style_btn_pr.body.grad_color = lv_color_hex3(0x24A);
|
||||
style_btn_pr.body.shadow.width = 2;
|
||||
style_btn_pr.text.color = lv_color_hex3(0xBCD);
|
||||
|
||||
lv_btn_set_style(btn, LV_BTN_STYLE_REL, &style_btn_rel); /*Set the button's released style*/
|
||||
lv_btn_set_style(btn, LV_BTN_STYLE_PR, &style_btn_pr); /*Set the button's pressed style*/
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Slider and object alignment
|
||||
```c
|
||||
lv_obj_t * label;
|
||||
|
||||
...
|
||||
|
||||
/* Create a slider in the center of the display */
|
||||
lv_obj_t * slider = lv_slider_create(lv_scr_act(), NULL);
|
||||
lv_obj_set_width(slider, 200); /*Set the width*/
|
||||
lv_obj_align(slider, NULL, LV_ALIGN_CENTER, 0, 0); /*Align to the center of the parent (screen)*/
|
||||
lv_obj_set_event_cb(slider, slider_event_cb); /*Assign an event function*/
|
||||
|
||||
/* Create a label below the slider */
|
||||
label = lv_label_create(lv_scr_act(), NULL);
|
||||
lv_label_set_text(label, "0");
|
||||
lv_obj_set_auto_realign(slider, true);
|
||||
lv_obj_align(label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
|
||||
|
||||
...
|
||||
|
||||
void slider_event_cb(lv_obj_t * slider, lv_event_t event)
|
||||
{
|
||||
if(event == LV_EVENT_VALUE_CHANGED) {
|
||||
static char buf[4]; /* max 3 bytes for number plus 1 null terminating byte */
|
||||
snprintf(buf, 4, "%u", lv_slider_get_value(slider));
|
||||
lv_label_set_text(slider_label, buf); /*Refresh the text*/
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
|
||||
### List and themes
|
||||
```c
|
||||
/*Texts of the list elements*/
|
||||
const char * txts[] = {"First", "Second", "Third", "Forth", "Fifth", "Sixth", NULL};
|
||||
|
||||
/* Initialize and set a theme. `LV_THEME_NIGHT` needs to enabled in lv_conf.h. */
|
||||
lv_theme_t * th = lv_theme_night_init(20, NULL);
|
||||
lv_theme_set_current(th);
|
||||
|
||||
/*Create a list*/
|
||||
lv_obj_t* list = lv_list_create(lv_scr_act(), NULL);
|
||||
lv_obj_set_size(list, 120, 180);
|
||||
lv_obj_set_pos(list, 10, 10);
|
||||
|
||||
/*Add buttons*/
|
||||
uint8_t i;
|
||||
for(i = 0; txts[i]; i++) {
|
||||
lv_obj_t * btn = lv_list_add_btn(list, LV_SYMBOL_FILE, txts[i]);
|
||||
lv_obj_set_event_cb(btn, list_event); /*Assign event function*/
|
||||
lv_btn_set_toggle(btn, true); /*Enable on/off states*/
|
||||
}
|
||||
|
||||
/* Initialize and set an other theme. `LV_THEME_MATERIAL` needs to enabled in lv_conf.h.
|
||||
* If `LV_TEHE_LIVE_UPDATE 1` then the previous list's style will be updated too.*/
|
||||
th = lv_theme_material_init(210, NULL);
|
||||
lv_theme_set_current(th);
|
||||
|
||||
/*Create an other list*/
|
||||
list = lv_list_create(lv_scr_act(), NULL);
|
||||
lv_obj_set_size(list, 120, 180);
|
||||
lv_obj_set_pos(list, 150, 10);
|
||||
|
||||
/*Add buttons with the same texts*/
|
||||
for(i = 0; txts[i]; i++) {
|
||||
lv_obj_t * btn = lv_list_add_btn(list, LV_SYMBOL_FILE, txts[i]);
|
||||
lv_obj_set_event_cb(btn, list_event);
|
||||
lv_btn_set_toggle(btn, true);
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
static void list_event(lv_obj_t * btn, lv_event_t e)
|
||||
{
|
||||
if(e == LV_EVENT_CLICKED) {
|
||||
printf("%s\n", lv_list_get_btn_text(btn));
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||

|
||||
|
||||
### Use LittlevGL from Micropython
|
||||
Learn more about [Micropython](https://docs.littlevgl.com/en/html/get-started/micropython).
|
||||
### LVGL from Micropython
|
||||
Learn more about [Micropython](https://docs.lvgl.io/latest/en/html/get-started/micropython.html).
|
||||
```python
|
||||
# Create a Button and a Label
|
||||
scr = lv.obj()
|
||||
@@ -377,22 +155,6 @@ lv.scr_load(scr)
|
||||
```
|
||||
|
||||
## Contributing
|
||||
To ask questions please use the [Forum](https://forum.littlevgl.com).
|
||||
For development-related things (bug reports, feature suggestions) use [GitHub's Issue tracker](https://github.com/littlevgl/lvgl/issues).
|
||||
LVGL is an open project and contribution is very welcome. There are many ways to contribute from simply speaking about your project, through writing examples, improving the documentation, fixing bugs to hosing your own project under in LVGL.
|
||||
|
||||
If you are interested in contributing to LittlevGL you can
|
||||
- **Help others** in the [Forum](https://forum.littlevgl.com).
|
||||
- **Inspire people** by speaking about your project in [My project](https://forum.littlevgl.com/c/my-projects) category in the Forum or add it to the [References](https://blog.littlevgl.com/2018-12-26/references) post
|
||||
- **Improve and/or translate the documentation.** Go to the [Documentation](https://github.com/littlevgl/docs) repository to learn more
|
||||
- **Write a blog post** about your experiences. See how to do it in the [Blog](https://github.com/littlevgl/blog) repository
|
||||
- **Report and/or fix bugs** in [GitHub's issue tracker](https://github.com/littlevgl/lvgl/issues)
|
||||
- **Help in the developement**. Check the [Open issues](https://github.com/littlevgl/lvgl/issues) especially the ones with [Help wanted](https://github.com/littlevgl/lvgl/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) label and tell your ideas about a topic or implement a feature.
|
||||
|
||||
It should be useful to read the
|
||||
- [Contributing guide](https://blog.littlevgl.com/2018-12-06/contributing)
|
||||
- [Coding style guide](https://github.com/littlevgl/lvgl/blob/master/docs/CODING_STYLE.md)
|
||||
|
||||
## Donate
|
||||
If you are pleased with the library, found it useful, or you are happy with the support you got, please help its further development:
|
||||
|
||||
[](https://littlevgl.com/donate)
|
||||
For a detailed description of contribution opportunities visit the [Contributing](https://docs.lvgl.io/latest/en/html/contributing/index.html) section of the documentation.
|
||||
|
||||
29
a.patch
Normal file
29
a.patch
Normal file
@@ -0,0 +1,29 @@
|
||||
diff --git a/scripts/release.py b/scripts/release.py
|
||||
index 28370c66..bc5234e7 100755
|
||||
--- a/scripts/release.py
|
||||
+++ b/scripts/release.py
|
||||
@@ -395,12 +395,12 @@ def docs_update_dev_version():
|
||||
os.chdir("../")
|
||||
|
||||
|
||||
-def publish_dev():
|
||||
+def publish_dev_and_master():
|
||||
pub_cmd = "git checkout dev; git push origin dev"
|
||||
cmd("cd lvgl; " + pub_cmd)
|
||||
+ pub_cmd = "git checkout master; git push origin master"
|
||||
+ cmd("cd lvgl; " + pub_cmd)
|
||||
|
||||
- pub_cmd = "git checkout dev; git push origin dev"
|
||||
- cmd("cd docs; " + pub_cmd)
|
||||
cmd("cd docs; git checkout master; ./update.py latest dev")
|
||||
|
||||
def cleanup():
|
||||
@@ -463,7 +463,7 @@ if __name__ == '__main__':
|
||||
|
||||
lvgl_update_dev_version()
|
||||
docs_update_dev_version()
|
||||
- publish_dev()
|
||||
+ publish_dev_and_master()
|
||||
|
||||
cleanup()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Coding style
|
||||
|
||||
## File format
|
||||
Use [lv_misc/lv_templ.c](https://github.com/littlevgl/lvgl/blob/master/src/lv_misc/lv_templ.c) and [lv_misc/lv_templ.h](https://github.com/littlevgl/lvgl/blob/master/src/lv_misc/lv_templ.h)
|
||||
Use [lv_misc/lv_templ.c](https://github.com/lvgl/lvgl/blob/master/src/lv_misc/lv_templ.c) and [lv_misc/lv_templ.h](https://github.com/lvgl/lvgl/blob/master/src/lv_misc/lv_templ.h)
|
||||
|
||||
## Naming conventions
|
||||
* Words are separated by '_'
|
||||
@@ -15,17 +16,18 @@ Use [lv_misc/lv_templ.c](https://github.com/littlevgl/lvgl/blob/master/src/lv_mi
|
||||
* prefer `typedef struct` and `typedef enum` instead of `struct name` and `enum name`
|
||||
* always end `typedef struct` and `typedef enum` type names with `_t`
|
||||
* Abbreviations:
|
||||
* Use abbreviations on public names only if they become longer than 32 characters
|
||||
* Use only very straightforward (e.g. pos: position) or well-established (e.g. pr: press) abbreviations
|
||||
* Only words longer or equal than 6 characters can be abbreviated.
|
||||
* Abbreviate only if it makes the word at least half as long
|
||||
* Use only very straightforward and well-known abbreviations (e.g. pos: position, def: default, btn: button)
|
||||
|
||||
## Coding guide
|
||||
* Functions:
|
||||
* Try to write function shorter than is 50 lines
|
||||
* Always shorter than 100 lines (except very straightforwards)
|
||||
* Always shorter than 200 lines (except very straightforwards)
|
||||
* Variables:
|
||||
* One line, one declaration (BAD: char x, y;)
|
||||
* Use `<stdint.h>` (*uint8_t*, *int32_t* etc)
|
||||
* Declare variables when needed (not all at function start)
|
||||
* Declare variables where needed (not all at function start)
|
||||
* Use the smallest required scope
|
||||
* Variables in a file (outside functions) are always *static*
|
||||
* Do not use global variables (use functions to set/get static variables)
|
||||
@@ -84,11 +86,4 @@ void lv_label_set_text(lv_obj_t * label, const char * text)
|
||||
|
||||
Use 4 spaces indentation instead of tab.
|
||||
|
||||
You can use **astyle** to format the code. The required config flies are: `docs/astyle_c` and `docs/astyle_h`.
|
||||
To format the source files:
|
||||
`$ find . -type f -name "*.c" | xargs astyle --options=docs/astyle_c`
|
||||
|
||||
To format the header files:
|
||||
`$ find . -type f -name "*.h" | xargs astyle --options=docs/astyle_h`
|
||||
|
||||
Append `-n` to the end to skip creation of backup file OR use `$ find . -type f -name "*.bak" -delete` (for source file's backups) and `find . -type f -name "*.orig" -delete` (for header file's backups)
|
||||
You can use **astyle** to format the code. Run `code-formatter.sh` from the `scrips` folder.
|
||||
|
||||
@@ -1,111 +1,5 @@
|
||||
# Contributing to Littlev Graphics Library
|
||||
# Contributing to LVGL
|
||||
|
||||
**Do you have some free time to spend with programming?
|
||||
Are you working on an Embedded GUI project with LittlevGL?
|
||||
See how can you help to improve the graphics library!**
|
||||
Thank you for considering contributing to LVGL.
|
||||
|
||||
There are many ways to join the community. If you have some time to work with us I'm sure you will find something that fits you! You can:
|
||||
- help others in the [Forum](https://forum.littlevgl.com/)
|
||||
- improve and/or translate the documentation
|
||||
- write a blog post about your experiences
|
||||
- report and/or fix bugs
|
||||
- suggest and/or implement new features
|
||||
|
||||
But first, start with the most Frequently Asked Questions.
|
||||
|
||||
# FAQ about contributing
|
||||
|
||||
## Where can I write my question and remarks?
|
||||
|
||||
We use the [Forum](https://forum.littlevgl.com/) to ask and answer questions and [GitHub's issue tracker](https://github.com/littlevgl/lvgl/issues) for development-related discussion.
|
||||
|
||||
We have some simple rules:
|
||||
- Be kind and friendly.
|
||||
- Speak about one thing in one issue/topic.
|
||||
- Give feedback and close the issue or mark the topic as solved if your question is answered.
|
||||
- Tell what you experience or expect. _"The button is not working"_ is not enough info to get help.
|
||||
- If possible send an absolute minimal code example in order to reproduce the issue
|
||||
- Use [Markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) to format your post.
|
||||
|
||||
## How can I send fixes and improvements?
|
||||
|
||||
Merging new code happens via Pull Requests. If you are still not familiar with the Pull Requests (PR for short) here is a quick guide:
|
||||
1. **Fork** the [lvgl repository](https://github.com/littlevgl/lvgl). To do this click the "Fork" button in the top right corner. It will "copy" the `lvgl` repository to your GitHub account (`https://github.com/your_name?tab=repositories`)
|
||||
2. **Clone** the forked repository and add your changes
|
||||
3. **Create a PR** on GitHub from the page of your `lvgl` repository (`https://github.com/your_name/lvgl`) by hitting the "New pull request" button
|
||||
4. **Set the base branch**. It means where you want to merge your update. Fixes go to `master`, new features to the actual `dev-x.y` branch.
|
||||
5. **Describe** what is in the update. An example code is welcome if applicable.
|
||||
|
||||
Some advice:
|
||||
- If you are not sure about your fix or feature it's better to open an issue first and discuss the details there.
|
||||
- Maybe your fix or update won't be perfect at first. Don't be afraid, just improve it and push the new commits. The PR will be updated accordingly.
|
||||
- If your update needs some extra work it's okay to say: _"I'm busy now and I will improve it soon"_ or _"Sorry, I don't have time to improve it, I hope it helps in this form too"_.
|
||||
So it's better to say don't have time to continue than saying nothing.
|
||||
- Please read and follow this [guide about the coding style](https://github.com/littlevgl/lvgl/blob/master/docs/CODING_STYLE.md)
|
||||
|
||||
|
||||
## Where is the documentation?
|
||||
|
||||
You can read the documentation here: <https://docs.littlevgl.com/>
|
||||
You can edit the documentation here: <https://github.com/littlevgl/doc>
|
||||
|
||||
## Where is the blog?
|
||||
|
||||
You can read the blog here: <https://blog.littlevgl.com/>
|
||||
You can edit the blog here: <https://github.com/littlevgl/blog>
|
||||
|
||||
# So how and where can you contribute?
|
||||
|
||||
## Help others in the Forum
|
||||
|
||||
It's a great way to contribute to the library if you already use it.
|
||||
Just go to [https://forum.littlevgl.com/](https://forum.littlevgl.com/) a register (Google and GitHub login also works).
|
||||
Log in, read the titles and if you are already familiar with a topic, don't be shy, and write your suggestion.
|
||||
|
||||
## Improving and/or translating the documentation
|
||||
|
||||
If you would like to contribute to LittlevGL the documentation is the best place to start.
|
||||
|
||||
### Fix typos, add missing parts
|
||||
|
||||
If you find a typo, an obscure sentence or something which is not explained well enough in the [English documentation](https://docs.littlevgl.com/en/html/index.html)
|
||||
click the *"Edit on GitHub"* button in the top right corner and fix the issue by sending a Pull Request.
|
||||
|
||||
### Translate the documentation
|
||||
|
||||
If you have time and interest you can translate the documentation to your native language or any language you speak.
|
||||
You can join others to work on an already existing language or you can start a new one.
|
||||
|
||||
To translate the documentation we use [Zanata](https://zanata.org) which is an online translation platform.
|
||||
You will find the LittlevGL project here: [LittlevGL on Zanata](https://translate.zanata.org/iteration/view/littlevgl-docs/v6.0-doc1?dswid=3430)
|
||||
|
||||
To get started you need to:
|
||||
- register at [Zanata](https://zanata.org) which is an online translation platform.
|
||||
- comment to [this post](https://forum.littlevgl.com/t/translate-the-documentation/238?u=kisvegabor)
|
||||
- tell your username at *Zanata* and your selected language(s) to get permission the edit the translations
|
||||
|
||||
Note that a translation will be added to the documentation only if at least the [Porting section](https://docs.littlevgl.com/en/html/porting/index.html) is translated.
|
||||
|
||||
|
||||
## Writing a blog post about your experiences
|
||||
|
||||
Have you ported LittlevGL to a new platform? Have you created a fancy GUI? Do you know a great trick?
|
||||
You can share your knowledge on LittlevGL's blog! It's super easy to add your own post:
|
||||
- Fork and clone the [blog repository](https://github.com/littlevgl/blog)
|
||||
- Add your post in Markdown to the `_posts` folder.
|
||||
- Store the images and other resources in a dedicated folder in `assets`
|
||||
- Create a Pull Request
|
||||
|
||||
The blog uses [Jekyll](https://jekyllrb.com/) to convert the `.md` files to a webpage. You can easily [run Jekyll offline](https://jekyllrb.com/docs/) to check your post before creating the Pull request
|
||||
|
||||
## Reporting and/or fixing bugs
|
||||
For simple bugfixes (typos, missing error handling, fixing a warning) is fine to send a Pull request directly. However, for more complex bugs it's better to open an issue first. In the issue, you should describe how to reproduce the bug and even add the minimal code snippet.
|
||||
|
||||
## Suggesting and/or implementing new features
|
||||
If you have a good idea don't hesitate to share with us. It's even better if you have time to deal with its implementation. Don't be afraid if you still don't know LittlevGL well enough. We will help you to get started.
|
||||
|
||||
During the implementation don't forget the [Code style guide](https://github.com/littlevgl/lvgl/blob/master/docs/CODING_STYLE.md).
|
||||
|
||||
# Summary
|
||||
|
||||
I hope you have taken a liking to contribute to LittlevGL. A helpful and friendly community is waiting for you! :)
|
||||
For a detailed description of contribution opportunities, please visit the [Contributing](https://docs.lvgl.io/latest/en/html/contributing/index.html) section of the documentation.
|
||||
|
||||
38
docs/ROADMAP.md
Normal file
38
docs/ROADMAP.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# Roadmap
|
||||
|
||||
This is a summary for thenew fatures of the major releases and a collection of ideas.
|
||||
|
||||
This list indicates only the current intention and can be changed.
|
||||
|
||||
## v8
|
||||
Planned to September/October 2020
|
||||
- New scrolling:
|
||||
- See [feat/new-scroll](https://github.com/lvgl/lvgl/tree/feat/new-scroll) branch and [#1614](https://github.com/lvgl/lvgl/issues/1614)) issue.
|
||||
- Remove `lv_page` and support scrolling on `lv_obj`
|
||||
- Support "elastic" scrolling when scrolled in
|
||||
- Support scroll chaining among any objects types (not only `lv_pages`s)
|
||||
- Remove `lv_drag`. Similar effect can be achieved by setting the position in `LV_EVENT_PRESSING`
|
||||
- Add snapping?
|
||||
- Already working
|
||||
- New layouts:
|
||||
- See [#1615](https://github.com/lvgl/lvgl/issues/1615) issue
|
||||
- [CSS Flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/)-like layout support
|
||||
- Besides setting width/height in `px` add support to `partent percentage` and `screen percentage`.
|
||||
- Work in progress
|
||||
- Simplified File system interface ([feat/new_fs_api](https://github.com/lvgl/lvgl/tree/feat/new-fs-api) branch) to make porting easier
|
||||
- Work in progress
|
||||
- Remove the align parameter from `lv_canvas_draw_text`
|
||||
|
||||
## v9
|
||||
- Simplify `group`s. Discussion is [here](https://forum.lvgl.io/t/lv-group-tabindex/2927/3).
|
||||
|
||||
## Ideas
|
||||
- Unit testing (gtest?). See [#1658](https://github.com/lvgl/lvgl/issues/1658)
|
||||
- Benchmarking (gem5?). See [#1660](https://github.com/lvgl/lvgl/issues/1660)
|
||||
- CPP binding. See [Forum](https://forum.lvgl.io/t/is-it-possible-to-officially-support-optional-cpp-api/2736)
|
||||
- Optmize font decompression
|
||||
- Switch to RGBA colors in styles
|
||||
- Need coverage report for tests
|
||||
- Need static analize (via coverity.io or somehing else)
|
||||
- Support dot_begin and dot_middle long modes for labels
|
||||
- Add new label alignment modes. [#1656](https://github.com/lvgl/lvgl/issues/1656)
|
||||
119
examples/arduino/ESP32_TFT_eSPI/ESP32_TFT_eSPI.ino
Normal file
119
examples/arduino/ESP32_TFT_eSPI/ESP32_TFT_eSPI.ino
Normal file
@@ -0,0 +1,119 @@
|
||||
#include <lvgl.h>
|
||||
#include <TFT_eSPI.h>
|
||||
|
||||
TFT_eSPI tft = TFT_eSPI(); /* TFT instance */
|
||||
static lv_disp_buf_t disp_buf;
|
||||
static lv_color_t buf[LV_HOR_RES_MAX * 10];
|
||||
|
||||
#if USE_LV_LOG != 0
|
||||
/* Serial debugging */
|
||||
void my_print(lv_log_level_t level, const char * file, uint32_t line, const char * dsc)
|
||||
{
|
||||
|
||||
Serial.printf("%s@%d->%s\r\n", file, line, dsc);
|
||||
Serial.flush();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Display flushing */
|
||||
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
|
||||
{
|
||||
uint32_t w = (area->x2 - area->x1 + 1);
|
||||
uint32_t h = (area->y2 - area->y1 + 1);
|
||||
|
||||
tft.startWrite();
|
||||
tft.setAddrWindow(area->x1, area->y1, w, h);
|
||||
tft.pushColors(&color_p->full, w * h, true);
|
||||
tft.endWrite();
|
||||
|
||||
lv_disp_flush_ready(disp);
|
||||
}
|
||||
|
||||
/*Read the touchpad*/
|
||||
bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
|
||||
{
|
||||
uint16_t touchX, touchY;
|
||||
|
||||
bool touched = tft.getTouch(&touchX, &touchY, 600);
|
||||
|
||||
if(!touched)
|
||||
{
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
}
|
||||
|
||||
if(touchX>screenWidth || touchY > screenHeight)
|
||||
{
|
||||
Serial.println("Y or y outside of expected parameters..");
|
||||
Serial.print("y:");
|
||||
Serial.print(touchX);
|
||||
Serial.print(" x:");
|
||||
Serial.print(touchY);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Set the coordinates*/
|
||||
data->point.x = touchX;
|
||||
data->point.y = touchY;
|
||||
|
||||
Serial.print("Data x");
|
||||
Serial.println(touchX);
|
||||
|
||||
Serial.print("Data y");
|
||||
Serial.println(touchY);
|
||||
|
||||
}
|
||||
|
||||
return false; /*Return `false` because we are not buffering and no more data to read*/
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200); /* prepare for possible serial debug */
|
||||
|
||||
lv_init();
|
||||
|
||||
#if USE_LV_LOG != 0
|
||||
lv_log_register_print_cb(my_print); /* register print function for debugging */
|
||||
#endif
|
||||
|
||||
tft.begin(); /* TFT init */
|
||||
tft.setRotation(1); /* Landscape orientation */
|
||||
|
||||
uint16_t calData[5] = { 275, 3620, 264, 3532, 1 };
|
||||
tft.setTouch(calData);
|
||||
|
||||
lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);
|
||||
|
||||
/*Initialize the display*/
|
||||
lv_disp_drv_t disp_drv;
|
||||
lv_disp_drv_init(&disp_drv);
|
||||
disp_drv.hor_res = 320;
|
||||
disp_drv.ver_res = 240;
|
||||
disp_drv.flush_cb = my_disp_flush;
|
||||
disp_drv.buffer = &disp_buf;
|
||||
lv_disp_drv_register(&disp_drv);
|
||||
|
||||
/*Initialize the (dummy) input device driver*/
|
||||
lv_indev_drv_t indev_drv;
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||
indev_drv.read_cb = my_touchpad_read;
|
||||
lv_indev_drv_register(&indev_drv);
|
||||
|
||||
/* Try an example from the lv_examples repository
|
||||
* https://github.com/lvgl/lv_examples*/
|
||||
lv_ex_btn_1();
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
lv_task_handler(); /* let the GUI do its work */
|
||||
delay(5);
|
||||
}
|
||||
44
examples/arduino/ESP32_TFT_eSPI/README.md
Normal file
44
examples/arduino/ESP32_TFT_eSPI/README.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Example for lv_arduino using a slider
|
||||
|
||||
This example has the screen set to 320x480 (ILI9488), change this by altering the following lines in the main ino file:
|
||||
|
||||
```C
|
||||
int screenWidth = 480;
|
||||
int screenHeight = 320;
|
||||
```
|
||||
|
||||
## Backlight
|
||||
|
||||
Change pin 32 to your preferred backlight pin using a PNP transistor (2N3906) or remove the following code and connect directly to +ve:
|
||||
|
||||
```C
|
||||
ledcSetup(10, 5000/*freq*/, 10 /*resolution*/);
|
||||
ledcAttachPin(32, 10);
|
||||
analogReadResolution(10);
|
||||
ledcWrite(10,768);
|
||||
```
|
||||
|
||||
## Theme selection
|
||||
|
||||
Change the following to change the theme:
|
||||
|
||||
```C
|
||||
lv_theme_t * th = lv_theme_night_init(210, NULL); //Set a HUE value and a Font for the Night Theme
|
||||
lv_theme_set_current(th);
|
||||
```
|
||||
|
||||
## Calibration
|
||||
|
||||
This is using the bodmer tft_espi driver for touch. To correctly set the calibration load the calibration sketch and replace the following with your values:
|
||||
|
||||
```C
|
||||
uint16_t calData[5] = { 275, 3620, 264, 3532, 1 };
|
||||
```
|
||||
|
||||
## Screen rotation
|
||||
|
||||
Check the following if you need to alter your screen rotation:
|
||||
|
||||
```C
|
||||
tft.setRotation(3);
|
||||
```
|
||||
37
examples/arduino/README.md
Normal file
37
examples/arduino/README.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# LVGL Arduino examples
|
||||
|
||||
LVGL can be installed via Arduino IDE Library Manager or as an .ZIP library.
|
||||
It will install [lv_exmaples](https://github.com/lvgl/lv_examples) which contains a lot of examples and demos to try LVGL.
|
||||
|
||||
## Example
|
||||
|
||||
There are simple examples which use the [TFT_eSPI](https://github.com/Bodmer/TFT_eSPI) library as a TFT driver to simplify testing.
|
||||
To get all this to work you have to setup TFT_eSPI to work with your TFT display type via editing the `User_Setup.h` file in TFT_eSPI library folder, or by selecting your own configurtion in the `User_Setup_Select.h` file in TFT_eSPI library folder.
|
||||
|
||||
LVGL library has its own configuration file called `lv_conf.h`. When LVGL is installed to followings needs to be done to configure it:
|
||||
1. Go to directory of the installed Arduno libraries
|
||||
2. Go to `lvgl` and copy `lv_conf_template.h` as `lv_conf.h` next to the `src` folder.
|
||||
3. Open `lv_conf.h` and change the first `#if 0` to `#if 1`
|
||||
4. Set the resolution of your display in `LV_HOR_RES_MAX` and `LV_VER_RES_MAX`
|
||||
5. Set the color depth of you display in `LV_COLOR_DEPTH`
|
||||
6. Set `LV_TICK_CUSTOM 1`
|
||||
|
||||
## Debugging
|
||||
|
||||
In case of trouble there are debug informations inside LVGL. In the `ESP32_TFT_eSPI` example there is `my_print` method, which allow to send this debug informations to the serial interface. To enable this feature you have to edit `lv_conf.h` file and enable logging in section `log settings`:
|
||||
|
||||
```c
|
||||
/*Log settings*/
|
||||
#define USE_LV_LOG 1 /*Enable/disable the log module*/
|
||||
#if LV_USE_LOG
|
||||
/* How important log should be added:
|
||||
* LV_LOG_LEVEL_TRACE A lot of logs to give detailed information
|
||||
* LV_LOG_LEVEL_INFO Log important events
|
||||
* LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem
|
||||
* LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail
|
||||
* LV_LOG_LEVEL_NONE Do not log anything
|
||||
*/
|
||||
# define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
|
||||
```
|
||||
|
||||
After enabling log module and setting LV_LOG_LEVEL accordingly the output log is sent to the `Serial` port @ 115200 Bd.
|
||||
@@ -54,20 +54,20 @@ void lv_port_disp_init(void)
|
||||
* Create a buffer for drawing
|
||||
*----------------------------*/
|
||||
|
||||
/* LittlevGL requires a buffer where it draws the objects. The buffer's has to be greater than 1 display row
|
||||
/* LVGL requires a buffer where it draws the objects. The buffer's has to be greater than 1 display row
|
||||
*
|
||||
* There are three buffering configurations:
|
||||
* 1. Create ONE buffer with some rows:
|
||||
* LittlevGL will draw the display's content here and writes it to your display
|
||||
* LVGL will draw the display's content here and writes it to your display
|
||||
*
|
||||
* 2. Create TWO buffer with some rows:
|
||||
* LittlevGL will draw the display's content to a buffer and writes it your display.
|
||||
* LVGL will draw the display's content to a buffer and writes it your display.
|
||||
* You should use DMA to write the buffer's content to the display.
|
||||
* It will enable LittlevGL to draw the next part of the screen to the other buffer while
|
||||
* It will enable LVGL to draw the next part of the screen to the other buffer while
|
||||
* the data is being sent form the first buffer. It makes rendering and flushing parallel.
|
||||
*
|
||||
* 3. Create TWO screen-sized buffer:
|
||||
* Similar to 2) but the buffer have to be screen sized. When LittlevGL is ready it will give the
|
||||
* Similar to 2) but the buffer have to be screen sized. When LVGL is ready it will give the
|
||||
* whole frame to display. This way you only need to change the frame buffer's address instead of
|
||||
* copying the pixels.
|
||||
* */
|
||||
@@ -91,7 +91,7 @@ void lv_port_disp_init(void)
|
||||
|
||||
|
||||
/*-----------------------------------
|
||||
* Register the display in LittlevGL
|
||||
* Register the display in LVGL
|
||||
*----------------------------------*/
|
||||
|
||||
lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
|
||||
@@ -81,7 +81,7 @@ void lv_port_fs_init(void)
|
||||
fs_init();
|
||||
|
||||
/*---------------------------------------------------
|
||||
* Register the file system interface in LittlevGL
|
||||
* Register the file system interface in LVGL
|
||||
*--------------------------------------------------*/
|
||||
|
||||
/* Add a simple drive to open images */
|
||||
@@ -140,14 +140,14 @@ void lv_port_indev_init(void)
|
||||
|
||||
/*Register a encoder input device*/
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_KEYPAD;
|
||||
indev_drv.type = LV_INDEV_TYPE_ENCODER;
|
||||
indev_drv.read_cb = encoder_read;
|
||||
indev_encoder = lv_indev_drv_register(&indev_drv);
|
||||
|
||||
/* Later you should create group(s) with `lv_group_t * group = lv_group_create()`,
|
||||
* add objects to the group with `lv_group_add_obj(group, obj)`
|
||||
* and assign this input device to group to navigate in it:
|
||||
* `lv_indev_set_group(indev_keypad, group);` */
|
||||
* `lv_indev_set_group(indev_encoder, group);` */
|
||||
|
||||
/*------------------
|
||||
* Button
|
||||
@@ -293,7 +293,7 @@ static bool keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||
if(act_key != 0) {
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
|
||||
/*Translate the keys to LittlevGL control characters according to your key definitions*/
|
||||
/*Translate the keys to LVGL control characters according to your key definitions*/
|
||||
switch(act_key) {
|
||||
case 1:
|
||||
act_key = LV_KEY_NEXT;
|
||||
27
library.json
27
library.json
@@ -1,14 +1,17 @@
|
||||
{
|
||||
"name": "lvgl",
|
||||
"version": "v6.1.2",
|
||||
"keywords": "graphics, gui, embedded, littlevgl",
|
||||
"description": "Graphics library to create embedded GUI with easy-to-use graphical elements, beautiful visual effects and low memory footprint. It offers anti-aliasing, opacity, and animations using only one frame buffer.",
|
||||
"repository":
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/littlevgl/lvgl.git"
|
||||
},
|
||||
"build": {
|
||||
"includeDir": "."
|
||||
}
|
||||
"name": "lvgl",
|
||||
"version": "7.4.0",
|
||||
"keywords": "graphics, gui, embedded, tft, lvgl",
|
||||
"description": "Graphics library to create embedded GUI with easy-to-use graphical elements, beautiful visual effects and low memory footprint. It offers anti-aliasing, opacity, and animations using only one frame buffer.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/lvgl/lvgl.git"
|
||||
},
|
||||
"build": {
|
||||
"includeDir": "."
|
||||
},
|
||||
"license": "MIT",
|
||||
"homepage": "https://lvgl.io",
|
||||
"frameworks": "*",
|
||||
"platforms": "*"
|
||||
}
|
||||
|
||||
10
library.properties
Normal file
10
library.properties
Normal file
@@ -0,0 +1,10 @@
|
||||
name=lvgl
|
||||
version=7.4.0
|
||||
author=kisvegabor
|
||||
maintainer=kisvegabor,embeddedt,pete-pjb
|
||||
sentence=Full-featured Graphics Library for Embedded Systems
|
||||
paragraph=Powerful and easy-to-use embedded GUI with many widgets, advanced visual effects (opacity, antialiasing, animations) and low memory requirements (16K RAM, 64K Flash).
|
||||
category=Display
|
||||
url=https://lvgl.io
|
||||
architectures=*
|
||||
includes=lvgl.h
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file lv_conf.h
|
||||
*
|
||||
* Configuration file for v7.4.0-dev
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
/* Color depth:
|
||||
* - 1: 1 byte per pixel
|
||||
* - 8: RGB233
|
||||
* - 8: RGB332
|
||||
* - 16: RGB565
|
||||
* - 32: ARGB8888
|
||||
*/
|
||||
@@ -43,9 +43,6 @@
|
||||
/*Images pixels with this color will not be drawn (with chroma keying)*/
|
||||
#define LV_COLOR_TRANSP LV_COLOR_LIME /*LV_COLOR_LIME: pure green*/
|
||||
|
||||
/* Enable chroma keying for indexed images. */
|
||||
#define LV_INDEXED_CHROMA 1
|
||||
|
||||
/* Enable anti-aliasing (lines, and radiuses will be smoothed) */
|
||||
#define LV_ANTIALIAS 1
|
||||
|
||||
@@ -100,6 +97,10 @@ typedef int16_t lv_coord_t;
|
||||
# define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/
|
||||
#endif /*LV_MEM_CUSTOM*/
|
||||
|
||||
/* Use the standard memcpy and memset instead of LVGL's own functions.
|
||||
* The standard functions might or might not be faster depending on their implementation. */
|
||||
#define LV_MEMCPY_MEMSET_STD 0
|
||||
|
||||
/* Garbage Collector settings
|
||||
* Used if lvgl is binded to higher level language and the memory is managed by that language */
|
||||
#define LV_ENABLE_GC 0
|
||||
@@ -123,7 +124,7 @@ typedef int16_t lv_coord_t;
|
||||
#define LV_INDEV_DEF_DRAG_LIMIT 10
|
||||
|
||||
/* Drag throw slow-down in [%]. Greater value -> faster slow-down */
|
||||
#define LV_INDEV_DEF_DRAG_THROW 20
|
||||
#define LV_INDEV_DEF_DRAG_THROW 10
|
||||
|
||||
/* Long press time in milliseconds.
|
||||
* Time to send `LV_EVENT_LONG_PRESSSED`) */
|
||||
@@ -153,7 +154,7 @@ typedef void * lv_anim_user_data_t;
|
||||
|
||||
#endif
|
||||
|
||||
/* 1: Enable shadow drawing*/
|
||||
/* 1: Enable shadow drawing on rectangles*/
|
||||
#define LV_USE_SHADOW 1
|
||||
#if LV_USE_SHADOW
|
||||
/* Allow buffering some shadow calculation
|
||||
@@ -163,12 +164,24 @@ typedef void * lv_anim_user_data_t;
|
||||
#define LV_SHADOW_CACHE_SIZE 0
|
||||
#endif
|
||||
|
||||
/*1: enable outline drawing on rectangles*/
|
||||
#define LV_USE_OUTLINE 1
|
||||
|
||||
/*1: enable pattern drawing on rectangles*/
|
||||
#define LV_USE_PATTERN 1
|
||||
|
||||
/*1: enable value string drawing on rectangles*/
|
||||
#define LV_USE_VALUE_STR 1
|
||||
|
||||
/* 1: Use other blend modes than normal (`LV_BLEND_MODE_...`)*/
|
||||
#define LV_USE_BLEND_MODES 1
|
||||
|
||||
/* 1: Use the `opa_scale` style property to set the opacity of an object and its children at once*/
|
||||
#define LV_USE_OPA_SCALE 1
|
||||
|
||||
/* 1: Use image zoom and rotation*/
|
||||
#define LV_USE_IMG_TRANSFORM 1
|
||||
|
||||
/* 1: Enable object groups (for keyboard/encoder navigation) */
|
||||
#define LV_USE_GROUP 1
|
||||
#if LV_USE_GROUP
|
||||
@@ -176,8 +189,11 @@ typedef void * lv_group_user_data_t;
|
||||
#endif /*LV_USE_GROUP*/
|
||||
|
||||
/* 1: Enable GPU interface*/
|
||||
#define LV_USE_GPU 1
|
||||
#define LV_USE_GPU 1 /*Only enables `gpu_fill_cb` and `gpu_blend_cb` in the disp. drv- */
|
||||
#define LV_USE_GPU_STM32_DMA2D 0
|
||||
/*If enabling LV_USE_GPU_STM32_DMA2D, LV_GPU_DMA2D_CMSIS_INCLUDE must be defined to include path of CMSIS header of target processor
|
||||
e.g. "stm32f769xx.h" or "stm32f429xx.h" */
|
||||
#define LV_GPU_DMA2D_CMSIS_INCLUDE
|
||||
|
||||
/* 1: Enable file system (might be required for images */
|
||||
#define LV_USE_FILESYSTEM 1
|
||||
@@ -192,6 +208,10 @@ typedef void * lv_fs_drv_user_data_t;
|
||||
/*1: Show CPU usage and FPS count in the right bottom corner*/
|
||||
#define LV_USE_PERF_MONITOR 0
|
||||
|
||||
/*1: Use the functions and types from the older API if possible */
|
||||
#define LV_USE_API_EXTENSION_V6 1
|
||||
#define LV_USE_API_EXTENSION_V7 1
|
||||
|
||||
/*========================
|
||||
* Image decoder and cache
|
||||
*========================*/
|
||||
@@ -216,6 +236,10 @@ typedef void * lv_img_decoder_user_data_t;
|
||||
/*=====================
|
||||
* Compiler settings
|
||||
*====================*/
|
||||
|
||||
/* For big endian systems set to 1 */
|
||||
#define LV_BIG_ENDIAN_SYSTEM 0
|
||||
|
||||
/* Define a custom attribute to `lv_tick_inc` function */
|
||||
#define LV_ATTRIBUTE_TICK_INC
|
||||
|
||||
@@ -246,6 +270,10 @@ typedef void * lv_img_decoder_user_data_t;
|
||||
*/
|
||||
#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning
|
||||
|
||||
/* Prefix variables that are used in GPU accelerated operations, often these need to be
|
||||
* placed in RAM sections that are DMA accessible */
|
||||
#define LV_ATTRIBUTE_DMA
|
||||
|
||||
/*===================
|
||||
* HAL settings
|
||||
*==================*/
|
||||
@@ -254,8 +282,8 @@ typedef void * lv_img_decoder_user_data_t;
|
||||
* It removes the need to manually update the tick with `lv_tick_inc`) */
|
||||
#define LV_TICK_CUSTOM 0
|
||||
#if LV_TICK_CUSTOM == 1
|
||||
#define LV_TICK_CUSTOM_INCLUDE "something.h" /*Header for the sys time function*/
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current systime in ms*/
|
||||
#define LV_TICK_CUSTOM_INCLUDE "Arduino.h" /*Header for the system time function*/
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current system time in ms*/
|
||||
#endif /*LV_TICK_CUSTOM*/
|
||||
|
||||
typedef void * lv_disp_drv_user_data_t; /*Type of user data in the display driver*/
|
||||
@@ -327,15 +355,15 @@ typedef void * lv_indev_drv_user_data_t; /*Type of user data in the i
|
||||
|
||||
/* The built-in fonts contains the ASCII range and some Symbols with 4 bit-per-pixel.
|
||||
* The symbols are available via `LV_SYMBOL_...` defines
|
||||
* More info about fonts: https://docs.littlevgl.com/#Fonts
|
||||
* To create a new font go to: https://littlevgl.com/ttf-font-to-c-array
|
||||
* More info about fonts: https://docs.lvgl.io/v7/en/html/overview/font.html
|
||||
* To create a new font go to: https://lvgl.com/ttf-font-to-c-array
|
||||
*/
|
||||
|
||||
/* Montserrat fonts with bpp = 4
|
||||
* https://fonts.google.com/specimen/Montserrat */
|
||||
#define LV_FONT_MONTSERRAT_12 0
|
||||
#define LV_FONT_MONTSERRAT_14 0
|
||||
#define LV_FONT_MONTSERRAT_16 1
|
||||
#define LV_FONT_MONTSERRAT_14 1
|
||||
#define LV_FONT_MONTSERRAT_16 0
|
||||
#define LV_FONT_MONTSERRAT_18 0
|
||||
#define LV_FONT_MONTSERRAT_20 0
|
||||
#define LV_FONT_MONTSERRAT_22 0
|
||||
@@ -376,11 +404,20 @@ typedef void * lv_indev_drv_user_data_t; /*Type of user data in the i
|
||||
* but with > 10,000 characters if you see issues probably you need to enable it.*/
|
||||
#define LV_FONT_FMT_TXT_LARGE 0
|
||||
|
||||
/* Enables/disables support for compressed fonts. If it's disabled, compressed
|
||||
* glyphs cannot be processed by the library and won't be rendered.
|
||||
*/
|
||||
#define LV_USE_FONT_COMPRESSED 1
|
||||
|
||||
/* Enable subpixel rendering */
|
||||
#define LV_USE_FONT_SUBPX 1
|
||||
#if LV_USE_FONT_SUBPX
|
||||
/* Set the pixel order of the display.
|
||||
* Important only if "subpx fonts" are used.
|
||||
* With "normal" font it doesn't matter.
|
||||
*/
|
||||
#define LV_FONT_SUBPX_BGR 0
|
||||
#endif
|
||||
|
||||
/*Declare the type of the user data of fonts (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_font_user_data_t;
|
||||
@@ -390,20 +427,40 @@ typedef void * lv_font_user_data_t;
|
||||
*================*/
|
||||
|
||||
/*Always enable at least on theme*/
|
||||
#define LV_USE_THEME_EMPTY 0 /*No theme, you can apply your styles as you need*/
|
||||
#define LV_USE_THEME_TEMPLATE 0 /*Simple to the create your theme based on it*/
|
||||
#define LV_USE_THEME_MATERIAL 1 /*A fast and impressive theme*/
|
||||
#define LV_USE_THEME_MONO 0 /*Mono-color theme for monochrome displays*/
|
||||
|
||||
/* No theme, you can apply your styles as you need
|
||||
* No flags. Set LV_THEME_DEFAULT_FLAG 0 */
|
||||
#define LV_USE_THEME_EMPTY 1
|
||||
|
||||
/*Simple to the create your theme based on it
|
||||
* No flags. Set LV_THEME_DEFAULT_FLAG 0 */
|
||||
#define LV_USE_THEME_TEMPLATE 1
|
||||
|
||||
/* A fast and impressive theme.
|
||||
* Flags:
|
||||
* LV_THEME_MATERIAL_FLAG_LIGHT: light theme
|
||||
* LV_THEME_MATERIAL_FLAG_DARK: dark theme
|
||||
* LV_THEME_MATERIAL_FLAG_NO_TRANSITION: disable transitions (state change animations)
|
||||
* LV_THEME_MATERIAL_FLAG_NO_FOCUS: disable indication of focused state)
|
||||
* */
|
||||
#define LV_USE_THEME_MATERIAL 1
|
||||
|
||||
/* Mono-color theme for monochrome displays.
|
||||
* If LV_THEME_DEFAULT_COLOR_PRIMARY is LV_COLOR_BLACK the
|
||||
* texts and borders will be black and the background will be
|
||||
* white. Else the colors are inverted.
|
||||
* No flags. Set LV_THEME_DEFAULT_FLAG 0 */
|
||||
#define LV_USE_THEME_MONO 1
|
||||
|
||||
#define LV_THEME_DEFAULT_INCLUDE <stdint.h> /*Include a header for the init. function*/
|
||||
#define LV_THEME_DEFAULT_INIT lv_theme_material_init
|
||||
#define LV_THEME_DEFAULT_COLOR_PRIMARY LV_COLOR_RED
|
||||
#define LV_THEME_DEFAULT_COLOR_SECONDARY LV_COLOR_BLUE
|
||||
#define LV_THEME_DEFAULT_COLOR_PRIMARY lv_color_hex(0x01a2b1)
|
||||
#define LV_THEME_DEFAULT_COLOR_SECONDARY lv_color_hex(0x44d1b6)
|
||||
#define LV_THEME_DEFAULT_FLAG LV_THEME_MATERIAL_FLAG_LIGHT
|
||||
#define LV_THEME_DEFAULT_FONT_SMALL &lv_font_montserrat_16
|
||||
#define LV_THEME_DEFAULT_FONT_NORMAL &lv_font_montserrat_16
|
||||
#define LV_THEME_DEFAULT_FONT_SUBTITLE &lv_font_montserrat_16
|
||||
#define LV_THEME_DEFAULT_FONT_TITLE &lv_font_montserrat_16
|
||||
#define LV_THEME_DEFAULT_FONT_SMALL &lv_font_montserrat_14
|
||||
#define LV_THEME_DEFAULT_FONT_NORMAL &lv_font_montserrat_14
|
||||
#define LV_THEME_DEFAULT_FONT_SUBTITLE &lv_font_montserrat_14
|
||||
#define LV_THEME_DEFAULT_FONT_TITLE &lv_font_montserrat_14
|
||||
|
||||
/*=================
|
||||
* Text settings
|
||||
@@ -458,6 +515,8 @@ typedef void * lv_font_user_data_t;
|
||||
# define LV_SPRINTF_INCLUDE <stdio.h>
|
||||
# define lv_snprintf snprintf
|
||||
# define lv_vsnprintf vsnprintf
|
||||
#else /*!LV_SPRINTF_CUSTOM*/
|
||||
# define LV_SPRINTF_DISABLE_FLOAT 1
|
||||
#endif /*LV_SPRINTF_CUSTOM*/
|
||||
|
||||
/*===================
|
||||
@@ -476,7 +535,7 @@ typedef void * lv_obj_user_data_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*1: enable `lv_obj_realaign()` based on `lv_obj_align()` parameters*/
|
||||
/*1: enable `lv_obj_realign()` based on `lv_obj_align()` parameters*/
|
||||
#define LV_USE_OBJ_REALIGN 1
|
||||
|
||||
/* Enable to make the object clickable on a larger area.
|
||||
@@ -490,7 +549,7 @@ typedef void * lv_obj_user_data_t;
|
||||
* LV OBJ X USAGE
|
||||
*================*/
|
||||
/*
|
||||
* Documentation of the object types: https://docs.littlevgl.com/#Object-types
|
||||
* Documentation of the object types: https://docs.lvgl.com/#Object-types
|
||||
*/
|
||||
|
||||
/*Arc (dependencies: -)*/
|
||||
@@ -501,16 +560,15 @@ typedef void * lv_obj_user_data_t;
|
||||
|
||||
/*Button (dependencies: lv_cont*/
|
||||
#define LV_USE_BTN 1
|
||||
#if LV_USE_BTN != 0
|
||||
/*Enable button-state animations - draw a circle on click (dependencies: LV_USE_ANIMATION)*/
|
||||
# define LV_BTN_INK_EFFECT 0
|
||||
#endif
|
||||
|
||||
/*Button matrix (dependencies: -)*/
|
||||
#define LV_USE_BTNMATRIX 1
|
||||
|
||||
/*Calendar (dependencies: -)*/
|
||||
#define LV_USE_CALENDAR 1
|
||||
#if LV_USE_CALENDAR
|
||||
# define LV_CALENDAR_WEEK_STARTS_MONDAY 0
|
||||
#endif
|
||||
|
||||
/*Canvas (dependencies: lv_img)*/
|
||||
#define LV_USE_CANVAS 1
|
||||
@@ -599,7 +657,7 @@ typedef void * lv_obj_user_data_t;
|
||||
#endif
|
||||
|
||||
/*Mask (dependencies: -)*/
|
||||
#define LV_USE_OBJMASK 0
|
||||
#define LV_USE_OBJMASK 1
|
||||
|
||||
/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/
|
||||
#define LV_USE_MSGBOX 1
|
||||
@@ -629,6 +687,9 @@ typedef void * lv_obj_user_data_t;
|
||||
# define LV_ROLLER_INF_PAGES 7
|
||||
#endif
|
||||
|
||||
/*Rotary (dependencies: lv_arc, lv_btn)*/
|
||||
#define LV_USE_ROTARY 1
|
||||
|
||||
/*Slider (dependencies: lv_bar)*/
|
||||
#define LV_USE_SLIDER 1
|
||||
|
||||
|
||||
22
lvgl.h
22
lvgl.h
@@ -2,7 +2,7 @@
|
||||
* @file lvgl.h
|
||||
* Include all LittleV GL related headers
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LVGL_H
|
||||
#define LVGL_H
|
||||
|
||||
@@ -10,6 +10,15 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/***************************
|
||||
* CURRENT VERSION OF LVGL
|
||||
***************************/
|
||||
#define LVGL_VERSION_MAJOR 7
|
||||
#define LVGL_VERSION_MINOR 4
|
||||
#define LVGL_VERSION_PATCH 0
|
||||
#define LVGL_VERSION_INFO ""
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
@@ -27,14 +36,12 @@ extern "C" {
|
||||
|
||||
#include "src/lv_core/lv_refr.h"
|
||||
#include "src/lv_core/lv_disp.h"
|
||||
#include "src/lv_core/lv_debug.h"
|
||||
|
||||
#include "src/lv_themes/lv_theme.h"
|
||||
|
||||
#include "src/lv_font/lv_font.h"
|
||||
#include "src/lv_font/lv_font_loader.h"
|
||||
#include "src/lv_font/lv_font_fmt_txt.h"
|
||||
#include "src/lv_misc/lv_bidi.h"
|
||||
#include "src/lv_misc/lv_txt_ap.h"
|
||||
#include "src/lv_misc/lv_printf.h"
|
||||
|
||||
#include "src/lv_widgets/lv_btn.h"
|
||||
@@ -75,14 +82,11 @@ extern "C" {
|
||||
|
||||
#include "src/lv_api_map.h"
|
||||
|
||||
//#define LV_BUILD_TEST 1
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
/*Current version of LittlevGL*/
|
||||
#define LVGL_VERSION_MAJOR 7
|
||||
#define LVGL_VERSION_MINOR 0
|
||||
#define LVGL_VERSION_PATCH 0
|
||||
#define LVGL_VERSION_INFO "rc"
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
|
||||
Binary file not shown.
BIN
scripts/built_in_font/SimSun.woff
Normal file
BIN
scripts/built_in_font/SimSun.woff
Normal file
Binary file not shown.
@@ -2,6 +2,12 @@
|
||||
|
||||
import os
|
||||
|
||||
print("\nGenerating 16 px CJK")
|
||||
os.system(u"./built_in_font_gen.py --size 16 -o lv_font_simsun_16_cjk.c --bpp 4 --font SimSun.woff -r 0x20-0x7f --symbols 一在有個我不這了他也就人都說而我們你了要會對及和與以很種的大能著她那上但年還可以最自己為來所他們兩各可為或好等又將因為於由從更被才已者每次把三什麼問題其讓此做再所以只與則台灣卻並位想去呢學生表示到公司將如果社會看小天因此新但是它中使工作全覺得使用這些裡並由於時候知道這樣一認為時間事過向可能中國美國到和幾系統政府大家國家許多生活跟已經大學研究因本二活動該世界應四希望方式內項啊下環境一些必須文化高孩子沒有不能如開始元不同仍網路日本用中心來對雖然重要地方進行關係市場太老師提供學校應該指出經濟其他家發展教育成為多非常便方面很多吃然後未發現電腦一樣而且心不過無法企業正服務較不會臺灣曾嗎空間看到五如何國內們無對於以及之後可是當人員比先產品資訊資料比較先生地除了大陸需要像在給歲請月些名另若亦地區技術至特別其實國際不要發生參加一定其中問台北包括講造成看像常即喜歡去沒出現政治話走單位一直吧是否當然整處理歷史了解那怎麼機會家聽所有只要朋友令甚至用真六呀情況還是錢方法點任何經驗藝術你們十主要媽媽增加提出為什麼以您計畫作利用東西在條設計找之間成長能夠決定學習誰見半時代完成帶相當同學件能力別人生命下來場會議容易開發民眾事情書事實有關自組織言多愛建立相關均產生多業者解決完全的話接受知約一般推動過程管理功能手打水要求小朋友教授難我國告訴內容結果調查家庭成立選擇經營然而父母寫人類至於買尤其配合進入例如得討論依作品情形資源原因啦妳運動觀念給軟體品質經過如此嗯精神影響之過好像成參與以後於是部分另外公園透過訓練努力研究具有共同所謂下行為合作經合作目標起來考慮長意見辦法音樂連受廠商隻受到一切或是中央某女性教學極獲得真的路來快國小部份工程女人舉行句只是段根據現象人民土地面對注意這裡新聞繼續相信政策變成計劃強調學人士前前存在制度意義代表課程該沒至需求人生那些成功爸爸產業負責民間雖影響直接幾乎分實際團體價值使得類形成科技這麼當七不但往本身標準似乎應用或者動物電話態度建設事業老那麼常常字坐舉辦自我有的具目的塊條件即使好十分多少放又電影科學執行邊委員會溝通開一起張針對員工引起自然那麼安全總統此外擁有並且事件設計研究所語言嚴重故事學術片設備之外車基本實在久套達到改善死結構住皆改變拿小組支持座醫院既僅值得學者八交通階段就是申請主管申請同感覺電視母親嘛香港記者壓力快樂喝敢院也許人們談生產怕就身體規定程度積極知識作為機構而是鼓勵角色狀況專家據清楚不僅比賽玩效果越保護共開放附近上父親專業經費曾經工作願意分別重視不少歡迎小孩小時中國人顯示中共出男人避免屬於實施聲音主義行動不可只有校園興趣山表現得回來主任裡面經常不再電子受思想頭終於謝謝協助除當地正式真正低性份因素推出上價格去認識方向責任說明工業大量做逐漸心理一點供須簡單運用觀察往往規劃減少重新業務報導仍然感到開放領域有效女要從事發揮人才反而行政銀行公共媒體提高代自然社區力量啊教育部愈超過維持家長結合校長通常缺乏委員特色結果有時教師之前遠控制本否則法少原則要臉通過建議工具作業達節目智慧來自而變化同樣形式站以為健康擔任人口規劃剛特殊原來道分傳統總是前往投資加強不斷對象追求加上比思考製作台北市取得出來加入台安排兒童國中範圍老人雙方牠北京年輕結束教程式婦女找到彼此全球成本回到部而已之下等變期間非小姐整體採用根本叫歐洲正在加以充滿系列隨著早等等頗不足總分析深報告不錯在於旁笑故消費者意識公尺民族為主大眾到底願度大概對方官員發表進一步自由正確豐富國民黨戰爭怎麼樣只好明顯改革表達肯定強高興哪樹適合茶別國外關心蘇聯成績人物聽到創造不必不論尚居民不管美麗伊拉克帶來有般永遠感情兒子這樣子起全部".encode('utf-8'))
|
||||
os.system('sed -i \'s|#include "lvgl/lvgl.h"|#include "../../lvgl.h"|\' lv_font_simsun_16_cjk.c')
|
||||
|
||||
exit()
|
||||
|
||||
print("Generating 12 px")
|
||||
os.system("./built_in_font_gen.py --size 12 -o lv_font_montserrat_12.c --bpp 4")
|
||||
os.system('sed -i \'s|#include "lvgl/lvgl.h"|#include "../../lvgl.h"|\' lv_font_montserrat_12.c')
|
||||
@@ -87,7 +93,7 @@ os.system("./built_in_font_gen.py --size 28 -o lv_font_montserrat_28_compressed.
|
||||
os.system('sed -i \'s|#include "lvgl/lvgl.h"|#include "../../lvgl.h"|\' lv_font_montserrat_28_compressed.c')
|
||||
|
||||
print("\nGenerating 16 px CJK")
|
||||
os.system(u"./built_in_font_gen.py --size 16 -o lv_font_simsun_16_cjk.c --bpp 4 --font SIMSUN.ttf -r 0x20-0x7f --symbols 一在有個我不這了他也就人都說而我們你了要會對及和與以很種的大能著她那上但年還可以最自己為來所他們兩各可為或好等又將因為於由從更被才已者每次把三什麼問題其讓此做再所以只與則台灣卻並位想去呢學生表示到公司將如果社會看小天因此新但是它中使工作全覺得使用這些裡並由於時候知道這樣一認為時間事過向可能中國美國到和幾系統政府大家國家許多生活跟已經大學研究因本二活動該世界應四希望方式內項啊下環境一些必須文化高孩子沒有不能如開始元不同仍網路日本用中心來對雖然重要地方進行關係市場太老師提供學校應該指出經濟其他家發展教育成為多非常便方面很多吃然後未發現電腦一樣而且心不過無法企業正服務較不會臺灣曾嗎空間看到五如何國內們無對於以及之後可是當人員比先產品資訊資料比較先生地除了大陸需要像在給歲請月些名另若亦地區技術至特別其實國際不要發生參加一定其中問台北包括講造成看像常即喜歡去沒出現政治話走單位一直吧是否當然整處理歷史了解那怎麼機會家聽所有只要朋友令甚至用真六呀情況還是錢方法點任何經驗藝術你們十主要媽媽增加提出為什麼以您計畫作利用東西在條設計找之間成長能夠決定學習誰見半時代完成帶相當同學件能力別人生命下來場會議容易開發民眾事情書事實有關自組織言多愛建立相關均產生多業者解決完全的話接受知約一般推動過程管理功能手打水要求小朋友教授難我國告訴內容結果調查家庭成立選擇經營然而父母寫人類至於買尤其配合進入例如得討論依作品情形資源原因啦妳運動觀念給軟體品質經過如此嗯精神影響之過好像成參與以後於是部分另外公園透過訓練努力研究具有共同所謂下行為合作經合作目標起來考慮長意見辦法音樂連受廠商隻受到一切或是中央某女性教學極獲得真的路來快國小部份工程女人舉行句只是段根據現象人民土地面對注意這裡新聞繼續相信政策變成計劃強調學人士前前存在制度意義代表課程該沒至需求人生那些成功爸爸產業負責民間雖影響直接幾乎分實際團體價值使得類形成科技這麼當七不但往本身標準似乎應用或者動物電話態度建設事業老那麼常常字坐舉辦自我有的具目的塊條件即使好十分多少放又電影科學執行邊委員會溝通開一起張針對員工引起自然那麼安全總統此外擁有並且事件設計研究所語言嚴重故事學術片設備之外車基本實在久套達到改善死結構住皆改變拿小組支持座醫院既僅值得學者八交通階段就是申請主管申請同感覺電視母親嘛香港記者壓力快樂喝敢院也許人們談生產怕就身體規定程度積極知識作為機構而是鼓勵角色狀況專家據清楚不僅比賽玩效果越保護共開放附近上父親專業經費曾經工作願意分別重視不少歡迎小孩小時中國人顯示中共出男人避免屬於實施聲音主義行動不可只有校園興趣山表現得回來主任裡面經常不再電子受思想頭終於謝謝協助除當地正式真正低性份因素推出上價格去認識方向責任說明工業大量做逐漸心理一點供須簡單運用觀察往往規劃減少重新業務報導仍然感到開放領域有效女要從事發揮人才反而行政銀行公共媒體提高代自然社區力量啊教育部愈超過維持家長結合校長通常缺乏委員特色結果有時教師之前遠控制本否則法少原則要臉通過建議工具作業達節目智慧來自而變化同樣形式站以為健康擔任人口規劃剛特殊原來道分傳統總是前往投資加強不斷對象追求加上比思考製作台北市取得出來加入台安排兒童國中範圍老人雙方牠北京年輕結束教程式婦女找到彼此全球成本回到部而已之下等變期間非小姐整體採用根本叫歐洲正在加以充滿系列隨著早等等頗不足總分析深報告不錯在於旁笑故消費者意識公尺民族為主大眾到底願度大概對方官員發表進一步自由正確豐富國民黨戰爭怎麼樣只好明顯改革表達肯定強高興哪樹適合茶別國外關心蘇聯成績人物聽到創造不必不論尚居民不管美麗伊拉克帶來有般永遠感情兒子這樣子起全部".encode('utf-8'))
|
||||
os.system(u"./built_in_font_gen.py --size 16 -o lv_font_simsun_16_cjk.c --bpp 4 --font SimSun.woff -r 0x20-0x7f --symbols 一在有個我不這了他也就人都說而我們你了要會對及和與以很種的大能著她那上但年還可以最自己為來所他們兩各可為或好等又將因為於由從更被才已者每次把三什麼問題其讓此做再所以只與則台灣卻並位想去呢學生表示到公司將如果社會看小天因此新但是它中使工作全覺得使用這些裡並由於時候知道這樣一認為時間事過向可能中國美國到和幾系統政府大家國家許多生活跟已經大學研究因本二活動該世界應四希望方式內項啊下環境一些必須文化高孩子沒有不能如開始元不同仍網路日本用中心來對雖然重要地方進行關係市場太老師提供學校應該指出經濟其他家發展教育成為多非常便方面很多吃然後未發現電腦一樣而且心不過無法企業正服務較不會臺灣曾嗎空間看到五如何國內們無對於以及之後可是當人員比先產品資訊資料比較先生地除了大陸需要像在給歲請月些名另若亦地區技術至特別其實國際不要發生參加一定其中問台北包括講造成看像常即喜歡去沒出現政治話走單位一直吧是否當然整處理歷史了解那怎麼機會家聽所有只要朋友令甚至用真六呀情況還是錢方法點任何經驗藝術你們十主要媽媽增加提出為什麼以您計畫作利用東西在條設計找之間成長能夠決定學習誰見半時代完成帶相當同學件能力別人生命下來場會議容易開發民眾事情書事實有關自組織言多愛建立相關均產生多業者解決完全的話接受知約一般推動過程管理功能手打水要求小朋友教授難我國告訴內容結果調查家庭成立選擇經營然而父母寫人類至於買尤其配合進入例如得討論依作品情形資源原因啦妳運動觀念給軟體品質經過如此嗯精神影響之過好像成參與以後於是部分另外公園透過訓練努力研究具有共同所謂下行為合作經合作目標起來考慮長意見辦法音樂連受廠商隻受到一切或是中央某女性教學極獲得真的路來快國小部份工程女人舉行句只是段根據現象人民土地面對注意這裡新聞繼續相信政策變成計劃強調學人士前前存在制度意義代表課程該沒至需求人生那些成功爸爸產業負責民間雖影響直接幾乎分實際團體價值使得類形成科技這麼當七不但往本身標準似乎應用或者動物電話態度建設事業老那麼常常字坐舉辦自我有的具目的塊條件即使好十分多少放又電影科學執行邊委員會溝通開一起張針對員工引起自然那麼安全總統此外擁有並且事件設計研究所語言嚴重故事學術片設備之外車基本實在久套達到改善死結構住皆改變拿小組支持座醫院既僅值得學者八交通階段就是申請主管申請同感覺電視母親嘛香港記者壓力快樂喝敢院也許人們談生產怕就身體規定程度積極知識作為機構而是鼓勵角色狀況專家據清楚不僅比賽玩效果越保護共開放附近上父親專業經費曾經工作願意分別重視不少歡迎小孩小時中國人顯示中共出男人避免屬於實施聲音主義行動不可只有校園興趣山表現得回來主任裡面經常不再電子受思想頭終於謝謝協助除當地正式真正低性份因素推出上價格去認識方向責任說明工業大量做逐漸心理一點供須簡單運用觀察往往規劃減少重新業務報導仍然感到開放領域有效女要從事發揮人才反而行政銀行公共媒體提高代自然社區力量啊教育部愈超過維持家長結合校長通常缺乏委員特色結果有時教師之前遠控制本否則法少原則要臉通過建議工具作業達節目智慧來自而變化同樣形式站以為健康擔任人口規劃剛特殊原來道分傳統總是前往投資加強不斷對象追求加上比思考製作台北市取得出來加入台安排兒童國中範圍老人雙方牠北京年輕結束教程式婦女找到彼此全球成本回到部而已之下等變期間非小姐整體採用根本叫歐洲正在加以充滿系列隨著早等等頗不足總分析深報告不錯在於旁笑故消費者意識公尺民族為主大眾到底願度大概對方官員發表進一步自由正確豐富國民黨戰爭怎麼樣只好明顯改革表達肯定強高興哪樹適合茶別國外關心蘇聯成績人物聽到創造不必不論尚居民不管美麗伊拉克帶來有般永遠感情兒子這樣子起全部".encode('utf-8'))
|
||||
os.system('sed -i \'s|#include "lvgl/lvgl.h"|#include "../../lvgl.h"|\' lv_font_simsun_16_cjk.c')
|
||||
|
||||
print("Generating 16 px Hebrew, Persian")
|
||||
|
||||
@@ -24,11 +24,27 @@
|
||||
--preserve-date
|
||||
--formatted
|
||||
--exclude=lv_conf_internal.h
|
||||
--exclude=../src/lv_font/lv_font_roboto_12.c
|
||||
--exclude=../src/lv_font/lv_font_roboto_12_subpx.c
|
||||
--exclude=../src/lv_font/lv_font_roboto_16.c
|
||||
--exclude=../src/lv_font/lv_font_roboto_22.c
|
||||
--exclude=../src/lv_font/lv_font_roboto_28.c
|
||||
--exclude=../src/lv_font/lv_font_roboto_28_compressed.c
|
||||
--exclude=../src/lv_font/lv_font_unscii_8.c
|
||||
--exclude=../src/lv_font/lv_font_montserrat_12.c
|
||||
--exclude=../src/lv_font/lv_font_montserrat_14.c
|
||||
--exclude=../src/lv_font/lv_font_montserrat_16.c
|
||||
--exclude=../src/lv_font/lv_font_montserrat_18.c
|
||||
--exclude=../src/lv_font/lv_font_montserrat_20.c
|
||||
--exclude=../src/lv_font/lv_font_montserrat_22.c
|
||||
--exclude=../src/lv_font/lv_font_montserrat_24.c
|
||||
--exclude=../src/lv_font/lv_font_montserrat_26.c
|
||||
--exclude=../src/lv_font/lv_font_montserrat_28.c
|
||||
--exclude=../src/lv_font/lv_font_montserrat_30.c
|
||||
--exclude=../src/lv_font/lv_font_montserrat_32.c
|
||||
--exclude=../src/lv_font/lv_font_montserrat_34.c
|
||||
--exclude=../src/lv_font/lv_font_montserrat_36.c
|
||||
--exclude=../src/lv_font/lv_font_montserrat_38.c
|
||||
--exclude=../src/lv_font/lv_font_montserrat_40.c
|
||||
--exclude=../src/lv_font/lv_font_montserrat_42.c
|
||||
--exclude=../src/lv_font/lv_font_montserrat_44.c
|
||||
--exclude=../src/lv_font/lv_font_montserrat_46.c
|
||||
--exclude=../src/lv_font/lv_font_montserrat_48.c
|
||||
--exclude=../src/lv_font/lv_font_montserrat_12_subpx.c
|
||||
--exclude=../src/lv_font/lv_font_montserrat_28_compressed.c
|
||||
--exclude=../src/lv_font/lv_font_simsun_16_cjk.c
|
||||
--exclude=../src/lv_font/lv_font_dejavu_16_persian_hebrew.c
|
||||
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3
|
||||
|
||||
'''
|
||||
Generates a checker file for lv_conf.h from lv_conf_templ.h define all the not defined values
|
||||
'''
|
||||
|
||||
|
||||
import sys
|
||||
import re
|
||||
|
||||
if sys.version_info < (3,6,0):
|
||||
print("Python >=3.6 is required", file=sys.stderr)
|
||||
exit(1)
|
||||
|
||||
fin = open("../lv_conf_template.h", "r")
|
||||
fout = open("../src/lv_conf_internal.h", "w")
|
||||
|
||||
|
||||
525
scripts/release.py
Executable file
525
scripts/release.py
Executable file
@@ -0,0 +1,525 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Release lvgl, lv_examples, lv_drivers. docs, blog and prepare the development of the next major, minoror bugfix release
|
||||
# Usage: ./release,py bugfix | minor | major
|
||||
# The option means what type of versin to prepare for development after release
|
||||
#
|
||||
# STEPS:
|
||||
# - clone all 5 repos
|
||||
# - get the version numnber from lvgl.h
|
||||
# - set release branch (e.g. "release/v7")
|
||||
# - prepare lvgl
|
||||
# - run lv_conf_internal.py
|
||||
# - run code formatter
|
||||
# - clear LVGL_VERSION_INFO (set to "")
|
||||
# - run Doxygen
|
||||
# - update the version in lvgl's library.json, library.properties, lv_conf_template.h
|
||||
# - update CHANGELOG.md
|
||||
# - commit changes
|
||||
# - prepare lv_examples
|
||||
# - upadte the required LVGL version in lv_examples.h (LV_VERSION_CHECK)
|
||||
# - update the version in lv_ex_conf_template.h
|
||||
# - prepare lv_drivers
|
||||
# - update the version in library.json, lv_drv_conf_template.h
|
||||
# - prepare docs
|
||||
# - update API XML
|
||||
# - clear the versiopn info (should be plain vx.y.z)
|
||||
# - tag all repos with the new version
|
||||
# - merge to release branches
|
||||
# - blog: add release post
|
||||
# - push tags and commits
|
||||
# - docs: run ./updade.py release/vX
|
||||
#
|
||||
# If --patch
|
||||
# - merge master to dev branches
|
||||
# - increment patch version by 1 and append "-dev". E.g. "vX.Y.(Z+1)-dev"
|
||||
# - update version numbers in lvgl and docs
|
||||
# - commit and push
|
||||
# - docs: run ./updade.py latest dev
|
||||
#
|
||||
# Else (not --patch)
|
||||
# - merge master to dev
|
||||
# - merge the dev to master
|
||||
# - increment version number like "vX.(Y+1).0-dev"
|
||||
# - apply the new version in dev branches of lvgl, lv_examples, lv_drivers, docs
|
||||
# - commit and push to dev branches
|
||||
# - docs: run ./updade.py latest dev
|
||||
|
||||
import re
|
||||
import os, fnmatch
|
||||
import os.path
|
||||
from os import path
|
||||
from datetime import date
|
||||
import sys
|
||||
|
||||
upstream_org_url = "https://github.com/lvgl/"
|
||||
workdir = "./release_tmp"
|
||||
proj_list = [ "lv_sim_eclipse_sdl"]
|
||||
|
||||
ver_major = -1
|
||||
ver_minor = -1
|
||||
ver_patch = -1
|
||||
|
||||
ver_str = ""
|
||||
dev_ver_str = ""
|
||||
release_br = ""
|
||||
release_note = ""
|
||||
|
||||
prepare_type = ['major', 'minor', 'bugfix']
|
||||
|
||||
dev_prepare = 'minor'
|
||||
|
||||
def upstream(repo):
|
||||
return upstream_org_url + repo + ".git"
|
||||
|
||||
def cmd(c, exit_on_err = True):
|
||||
print("\n" + c)
|
||||
r = os.system(c)
|
||||
if r:
|
||||
print("### Error: " + str(r))
|
||||
if exit_on_err: exit(int(r))
|
||||
|
||||
def define_set(fn, name, value):
|
||||
print("In " + fn + " set " + name + " to " + value)
|
||||
|
||||
new_content = ""
|
||||
s = r'^ *# *define +' + str(name).rstrip()
|
||||
|
||||
f = open(fn, "r")
|
||||
for i in f.read().splitlines():
|
||||
r = re.search(s, i)
|
||||
if r:
|
||||
d = i.split("define")
|
||||
i = d[0] + "define " + name + " " + value
|
||||
new_content += i + '\n'
|
||||
|
||||
f.close()
|
||||
|
||||
f = open(fn, "w")
|
||||
f.write(new_content)
|
||||
f.close()
|
||||
|
||||
def clone_repos():
|
||||
cmd("rm -fr " + workdir)
|
||||
cmd("mkdir " + workdir)
|
||||
os.chdir(workdir)
|
||||
|
||||
#For debuging just copy the repos
|
||||
#cmd("cp -a ../repos/. .")
|
||||
#return
|
||||
|
||||
cmd("git clone " + upstream("lvgl") + "; cd lvgl; git checkout master")
|
||||
cmd("git clone " + upstream("lv_examples") + "; cd lv_examples; git checkout master")
|
||||
cmd("git clone " + upstream("lv_drivers") + "; cd lv_drivers; git checkout master")
|
||||
cmd("git clone --recurse-submodules " + upstream("docs") + "; cd docs; git checkout master")
|
||||
cmd("git clone " + upstream("blog") + "; cd blog; git checkout master")
|
||||
|
||||
for p in proj_list:
|
||||
cmd("git clone " + upstream(p) + " --recurse-submodules ; cd " + p + "; git checkout master")
|
||||
|
||||
|
||||
def get_lvgl_version(br):
|
||||
print("Get LVGL's version")
|
||||
|
||||
global ver_str, ver_major, ver_minor, ver_patch, release_br
|
||||
|
||||
os.chdir("./lvgl")
|
||||
|
||||
cmd("git checkout " + br)
|
||||
|
||||
f = open("./lvgl.h", "r")
|
||||
|
||||
lastNum = re.compile(r'(?:[^\d]*(\d+)[^\d]*)+')
|
||||
for i in f.read().splitlines():
|
||||
r = re.search(r'^#define LVGL_VERSION_MAJOR ', i)
|
||||
if r:
|
||||
m = lastNum.search(i)
|
||||
if m: ver_major = m.group(1)
|
||||
|
||||
r = re.search(r'^#define LVGL_VERSION_MINOR ', i)
|
||||
if r:
|
||||
m = lastNum.search(i)
|
||||
if m: ver_minor = m.group(1)
|
||||
|
||||
r = re.search(r'^#define LVGL_VERSION_PATCH ', i)
|
||||
if r:
|
||||
m = lastNum.search(i)
|
||||
if m: ver_patch = m.group(1)
|
||||
|
||||
f.close()
|
||||
|
||||
cmd("git checkout master")
|
||||
|
||||
ver_str = "v" + str(ver_major) + "." + str(ver_minor) + "." + str(ver_patch)
|
||||
print("New version:" + ver_str)
|
||||
|
||||
release_br = "release/v" + ver_major
|
||||
|
||||
os.chdir("../")
|
||||
|
||||
def update_version():
|
||||
templ = fnmatch.filter(os.listdir('.'), '*templ*')
|
||||
|
||||
if templ[0]:
|
||||
print("Updating version in " + templ[0])
|
||||
cmd("sed -i -r 's/v[0-9]+\.[0-9]+\.[0-9]+/"+ ver_str +"/' " + templ[0])
|
||||
|
||||
if os.path.exists("library.json"):
|
||||
print("Updating version in library.json")
|
||||
cmd("sed -i -r 's/[0-9]+\.[0-9]+\.[0-9]+/"+ ver_str[1:] +"/' library.json")
|
||||
|
||||
if path.exists("library.properties"):
|
||||
print("Updating version in library.properties")
|
||||
cmd("sed -i -r 's/version=[0-9]+\.[0-9]+\.[0-9]+/"+ "version=" + ver_str[1:] + "/' library.properties")
|
||||
|
||||
def lvgl_prepare():
|
||||
print("Prepare lvgl")
|
||||
|
||||
global ver_str, ver_major, ver_minor, ver_patch
|
||||
|
||||
os.chdir("./lvgl")
|
||||
define_set("./lvgl.h", "LVGL_VERSION_INFO", '\"\"')
|
||||
|
||||
# Run some scripts
|
||||
os.chdir("./scripts")
|
||||
cmd("./code-format.sh")
|
||||
cmd("./lv_conf_checker.py")
|
||||
cmd("doxygen")
|
||||
os.chdir("../")
|
||||
|
||||
update_version()
|
||||
|
||||
#update CHANGLELOG
|
||||
new_content = ""
|
||||
f = open("./CHANGELOG.md", "r")
|
||||
|
||||
global release_note
|
||||
release_note = ""
|
||||
note_state = 0
|
||||
for i in f.read().splitlines():
|
||||
if note_state == 0:
|
||||
r = re.search(r'^## ' + ver_str, i)
|
||||
if r:
|
||||
i = i.replace("planned on ", "")
|
||||
note_state+=1
|
||||
|
||||
elif note_state == 1:
|
||||
r = re.search(r'^## ', i)
|
||||
if r:
|
||||
note_state+=1
|
||||
else:
|
||||
release_note += i + '\n'
|
||||
|
||||
new_content += i + '\n'
|
||||
|
||||
f.close()
|
||||
|
||||
f = open("./CHANGELOG.md", "w")
|
||||
f.write(new_content)
|
||||
f.close()
|
||||
|
||||
cmd('git commit -am "prepare to release ' + ver_str + '"')
|
||||
|
||||
os.chdir("../")
|
||||
|
||||
|
||||
def lv_examples_prepare():
|
||||
print("Prepare lv_examples")
|
||||
global ver_str, ver_major, ver_minor, ver_patch
|
||||
|
||||
os.chdir("./lv_examples")
|
||||
|
||||
update_version()
|
||||
|
||||
cmd("sed -i -r 's/LV_VERSION_CHECK\([0-9]+, *[0-9]+, *[0-9]+\)/"+ "LV_VERSION_CHECK(" + ver_major + ", " + ver_minor + ", " + ver_patch + ")/' lv_examples.h")
|
||||
|
||||
cmd('git commit -am "prepare to release ' + ver_str + '"')
|
||||
|
||||
os.chdir("../")
|
||||
|
||||
def lv_drivers_prepare():
|
||||
print("Prepare lv_drivers")
|
||||
global ver_str, ver_major, ver_minor, ver_patch
|
||||
|
||||
os.chdir("./lv_drivers")
|
||||
|
||||
update_version()
|
||||
|
||||
cmd('git commit -am "prepare to release ' + ver_str + '"')
|
||||
|
||||
os.chdir("../")
|
||||
|
||||
def docs_prepare():
|
||||
print("Prepare docs")
|
||||
global ver_str, ver_major, ver_minor, ver_patch
|
||||
|
||||
os.chdir("./docs")
|
||||
|
||||
cmd("git co latest --")
|
||||
cmd("rm -rf xml");
|
||||
cmd("cp -r ../lvgl/docs/api_doc/xml .");
|
||||
cmd("git add xml");
|
||||
|
||||
cmd("sed -i -r \"s/'v[0-9]+\.[0-9]+\.[0-9]+.*'/\'" + ver_str + "'/\" conf.py")
|
||||
|
||||
cmd('git commit -am "prepare to release ' + ver_str + '"')
|
||||
|
||||
os.chdir("../")
|
||||
|
||||
def blog_add_post():
|
||||
global ver_str, release_note
|
||||
|
||||
os.chdir("./blog/_posts")
|
||||
|
||||
post = "---\nlayout: post\ntitle: " + ver_str + " is released\nauthor: \"kisvegabor\"\ncover: /assets/release_cover.png\n---\n\n"
|
||||
post += release_note
|
||||
|
||||
today = date.today()
|
||||
d = today.strftime("%Y-%m-%d")
|
||||
|
||||
f = open(d + "-release_" + ver_str + ".md", "w")
|
||||
f.write(post)
|
||||
f.close()
|
||||
|
||||
cmd("git add .")
|
||||
cmd("git commit -am 'Add " + ver_str + " release post'")
|
||||
|
||||
os.chdir("../../")
|
||||
|
||||
def add_tags():
|
||||
global ver_str
|
||||
tag_cmd = " git tag -a " + ver_str + " -m 'Release " + ver_str + "' "
|
||||
cmd("cd lvgl; " + tag_cmd)
|
||||
cmd("cd lv_examples; " + tag_cmd)
|
||||
cmd("cd lv_drivers; " + tag_cmd)
|
||||
cmd("cd docs; " + tag_cmd)
|
||||
|
||||
def update_release_branches():
|
||||
global release_br
|
||||
merge_cmd = " git checkout " + release_br + "; git pull origin " + release_br + "; git merge master -X ours; git push origin " + release_br + "; git checkout master"
|
||||
cmd("cd lvgl; " + merge_cmd)
|
||||
cmd("cd lv_examples; " + merge_cmd)
|
||||
cmd("cd lv_drivers; " + merge_cmd)
|
||||
|
||||
merge_cmd = " git checkout " + release_br + "; git pull origin " + release_br + "; git merge latest -X ours; git push origin " + release_br + "; git checkout latest"
|
||||
cmd("cd docs; " + merge_cmd)
|
||||
|
||||
def publish_master():
|
||||
|
||||
#Merge LVGL master to dev first to avoid "merge-to-dev.yml" running asynchronous
|
||||
os.chdir("./lvgl")
|
||||
cmd("git checkout dev")
|
||||
cmd("git merge master -X theirs")
|
||||
cmd("git add .")
|
||||
cmd("git commit -am 'Merge master'")
|
||||
cmd("git push origin dev")
|
||||
cmd("git checkout master")
|
||||
os.chdir("../")
|
||||
|
||||
pub_cmd = "git push origin master; git push origin " + ver_str
|
||||
cmd("cd lvgl; " + pub_cmd)
|
||||
cmd("cd lv_examples; " + pub_cmd)
|
||||
cmd("cd lv_drivers; " + pub_cmd)
|
||||
|
||||
pub_cmd = "git push origin latest; git push origin " + ver_str
|
||||
cmd("cd docs; " + pub_cmd)
|
||||
cmd("cd docs; git checkout master; ./update.py " + release_br)
|
||||
|
||||
pub_cmd = "git push origin master"
|
||||
cmd("cd blog; " + pub_cmd)
|
||||
|
||||
|
||||
def merge_to_dev():
|
||||
merge_cmd = "git checkout dev; git pull origin dev; git merge master -X ours; git checkout master"
|
||||
cmd("cd lvgl; " + merge_cmd)
|
||||
|
||||
merge_cmd = "git checkout dev --; git pull origin dev; git merge latest -X ours; git checkout master"
|
||||
cmd("cd docs; " + merge_cmd)
|
||||
|
||||
|
||||
def merge_from_dev():
|
||||
merge_cmd = "git checkout master; git merge dev;"
|
||||
cmd("cd lvgl; " + merge_cmd)
|
||||
|
||||
merge_cmd = "git checkout latest -- ; git merge dev;"
|
||||
cmd("cd docs; " + merge_cmd)
|
||||
|
||||
|
||||
def lvgl_update_master_version():
|
||||
global ver_major, ver_minor, ver_patch, ver_str
|
||||
|
||||
os.chdir("./lvgl")
|
||||
|
||||
cmd("git checkout master")
|
||||
define_set("./lvgl.h", "LVGL_VERSION_MAJOR", ver_major)
|
||||
define_set("./lvgl.h", "LVGL_VERSION_MINOR", ver_minor)
|
||||
define_set("./lvgl.h", "LVGL_VERSION_PATCH", ver_patch)
|
||||
define_set("./lvgl.h", "LVGL_VERSION_INFO", "dev")
|
||||
|
||||
templ = fnmatch.filter(os.listdir('.'), '*templ*')
|
||||
if templ[0]:
|
||||
print("Updating version in " + templ[0])
|
||||
cmd("sed -i -r 's/v[0-9]+\.[0-9]+\.[0-9]+.*/"+ ver_str +"/' " + templ[0])
|
||||
|
||||
|
||||
cmd("git commit -am 'Update version'")
|
||||
|
||||
os.chdir("../")
|
||||
|
||||
def docs_update_latest_version():
|
||||
global ver_str
|
||||
|
||||
os.chdir("./docs")
|
||||
cmd("git checkout latest --")
|
||||
cmd("sed -i -r \"s/'v[0-9]+\.[0-9]+\.[0-9]+.*'/\'" + ver_str + "'/\" conf.py")
|
||||
cmd("git commit -am 'Update version'")
|
||||
cmd("git checkout master --")
|
||||
|
||||
os.chdir("../")
|
||||
|
||||
|
||||
def lvgl_update_dev_version():
|
||||
global ver_major, ver_minor, ver_patch, dev_ver_str
|
||||
|
||||
os.chdir("./lvgl")
|
||||
|
||||
cmd("git checkout dev")
|
||||
define_set("./lvgl.h", "LVGL_VERSION_MAJOR", ver_major)
|
||||
define_set("./lvgl.h", "LVGL_VERSION_MINOR", ver_minor)
|
||||
define_set("./lvgl.h", "LVGL_VERSION_PATCH", ver_patch)
|
||||
define_set("./lvgl.h", "LVGL_VERSION_INFO", "\"dev\"")
|
||||
|
||||
templ = fnmatch.filter(os.listdir('.'), '*templ*')
|
||||
if templ[0]:
|
||||
print("Updating version in " + templ[0])
|
||||
cmd("sed -i -r 's/v[0-9]+\.[0-9]+\.[0-9]+.*/"+ dev_ver_str +"/' " + templ[0])
|
||||
|
||||
|
||||
cmd("git commit -am 'Update dev version'")
|
||||
cmd("git checkout master")
|
||||
|
||||
os.chdir("../")
|
||||
|
||||
def docs_update_dev_version():
|
||||
global dev_ver_str
|
||||
|
||||
os.chdir("./docs")
|
||||
cmd("git checkout dev --")
|
||||
cmd("sed -i -r \"s/'v[0-9]+\.[0-9]+\.[0-9]+.*'/\'" + dev_ver_str + "'/\" conf.py")
|
||||
cmd("git commit -am 'Update dev version'")
|
||||
cmd("git checkout master --")
|
||||
|
||||
os.chdir("../")
|
||||
|
||||
|
||||
def publish_dev_and_master():
|
||||
pub_cmd = "git checkout dev; git push origin dev"
|
||||
cmd("cd lvgl; " + pub_cmd)
|
||||
pub_cmd = "git checkout master; git push origin master"
|
||||
cmd("cd lvgl; " + pub_cmd)
|
||||
|
||||
cmd("cd docs; git checkout master; ./update.py latest dev")
|
||||
|
||||
def projs_update():
|
||||
global proj_list, release_br, ver_str
|
||||
for p in proj_list:
|
||||
os.chdir("./" + p)
|
||||
cmd('git checkout master')
|
||||
print(p + ": upadte lvgl");
|
||||
cmd("cd lvgl; git co " + release_br + "; git pull origin " + release_br)
|
||||
cmd("cp -f lvgl/lv_conf_template.h lv_conf.h")
|
||||
cmd("sed -i -r 's/#if 0/#if 1/' lv_conf.h") # Enable lv_conf.h
|
||||
d = {}
|
||||
with open("confdef.txt") as f:
|
||||
for line in f:
|
||||
(key, val) = line.rstrip().split('\t')
|
||||
d[key] = val
|
||||
|
||||
for k,v in d.items():
|
||||
define_set("lv_conf.h", str(k), str(v))
|
||||
|
||||
if os.path.exists("lv_examples"):
|
||||
print(p + ": upadte lv_examples");
|
||||
cmd("cd lv_examples; git co " + release_br + "; git pull origin " + release_br)
|
||||
|
||||
if os.path.exists("lv_drivers"):
|
||||
print(p + ": upadte lv_drivers");
|
||||
cmd("cd lv_drivers " + release_br + "; git pull origin " + release_br)
|
||||
|
||||
msg = 'Update to ' + ver_str
|
||||
cmd("git add .")
|
||||
cmd('git commit -am "' + msg + '"')
|
||||
cmd('git push origin master')
|
||||
cmd("git tag -a " + ver_str + " -m '" + msg + "' " )
|
||||
cmd('git push origin ' + ver_str)
|
||||
|
||||
os.chdir("../")
|
||||
|
||||
|
||||
def cleanup():
|
||||
os.chdir("../")
|
||||
cmd("rm -fr " + workdir)
|
||||
|
||||
if __name__ == '__main__':
|
||||
dev_prepare = 'minor'
|
||||
if(len(sys.argv) != 2):
|
||||
print("Missing argument. Usage ./release.py bugfix | minor | major")
|
||||
print("Use minor by deafult")
|
||||
else:
|
||||
dev_prepare = sys.argv[1]
|
||||
|
||||
if not (dev_prepare in prepare_type):
|
||||
print("Invalid argument. Usage ./release.py bugfix | minor | major")
|
||||
exit(1)
|
||||
|
||||
clone_repos()
|
||||
get_lvgl_version("master")
|
||||
lvgl_prepare()
|
||||
lv_examples_prepare()
|
||||
lv_drivers_prepare()
|
||||
docs_prepare()
|
||||
blog_add_post()
|
||||
add_tags()
|
||||
update_release_branches()
|
||||
publish_master()
|
||||
|
||||
if dev_prepare == 'bugfix':
|
||||
ver_patch = str(int(ver_patch) + 1)
|
||||
ver_str = "v" + ver_major + "." + ver_minor + "." + ver_patch + "-dev"
|
||||
|
||||
print("Prepare bugfix version " + ver_str)
|
||||
|
||||
lvgl_update_master_version()
|
||||
docs_update_latest_version()
|
||||
|
||||
get_lvgl_version("dev")
|
||||
dev_ver_str = "v" + ver_major + "." + ver_minor + "." + ver_patch + "-dev"
|
||||
merge_to_dev()
|
||||
|
||||
lvgl_update_dev_version()
|
||||
docs_update_dev_version()
|
||||
publish_dev()
|
||||
else:
|
||||
get_lvgl_version("dev")
|
||||
if dev_prepare == 'minor':
|
||||
ver_minor = str(int(ver_minor) + 1)
|
||||
ver_patch = "0"
|
||||
else:
|
||||
ver_major = str(int(ver_major) + 1)
|
||||
ver_minor = "0"
|
||||
ver_patch = "0"
|
||||
|
||||
dev_ver_str = "v" + ver_major + "." + ver_minor + "." + ver_patch + "-dev"
|
||||
|
||||
print("Prepare minor version " + ver_str)
|
||||
|
||||
merge_to_dev()
|
||||
merge_from_dev()
|
||||
|
||||
lvgl_update_dev_version()
|
||||
docs_update_dev_version()
|
||||
publish_dev_and_master()
|
||||
|
||||
projs_update()
|
||||
cleanup()
|
||||
|
||||
@@ -1,189 +0,0 @@
|
||||
import re
|
||||
import os
|
||||
lastNum = re.compile(r'(?:[^\d]*(\d+)[^\d]*)+')
|
||||
|
||||
|
||||
def title(t):
|
||||
print("\n---------------------------------")
|
||||
print(t)
|
||||
print("---------------------------------")
|
||||
|
||||
|
||||
def cmd(c):
|
||||
print("\n" + c)
|
||||
os.system(c)
|
||||
|
||||
|
||||
def increment(s):
|
||||
""" look for the last sequence of number(s) in a string and increment """
|
||||
m = lastNum.search(s)
|
||||
if m:
|
||||
next = str(int(m.group(1))+1)
|
||||
start, end = m.span(1)
|
||||
s = s[:max(end-len(next), start)] + next + s[end:]
|
||||
return s, str(next)
|
||||
|
||||
|
||||
def lvgl_clone():
|
||||
title("lvgl: Clone")
|
||||
cmd("git clone https://github.com/littlevgl/lvgl.git")
|
||||
os.chdir("./lvgl")
|
||||
cmd("git co master")
|
||||
|
||||
def lvgl_update_version():
|
||||
title("lvgl: Update version number")
|
||||
|
||||
f = open("./src/lv_version.h", "r")
|
||||
|
||||
outbuf = ""
|
||||
major_ver = -1
|
||||
minor_ver = -1
|
||||
patch_ver = -1
|
||||
|
||||
for i in f.read().splitlines():
|
||||
r = re.search(r'^#define LVGL_VERSION_MAJOR ', i)
|
||||
if r:
|
||||
m = lastNum.search(i)
|
||||
if m: major_ver = m.group(1)
|
||||
|
||||
r = re.search(r'^#define LVGL_VERSION_MINOR ', i)
|
||||
if r:
|
||||
m = lastNum.search(i)
|
||||
if m: minor_ver = m.group(1)
|
||||
|
||||
r = re.search(r'^#define LVGL_VERSION_PATCH ', i)
|
||||
if r:
|
||||
i, patch_ver = increment(i)
|
||||
|
||||
|
||||
r = re.search(r'^#define LVGL_VERSION_INFO ', i)
|
||||
if r:
|
||||
i = "#define LVGL_VERSION_INFO \"\""
|
||||
|
||||
outbuf += i + '\n'
|
||||
|
||||
f.close()
|
||||
|
||||
f = open("./src/lv_version.h", "w")
|
||||
|
||||
f.write(outbuf)
|
||||
f.close()
|
||||
|
||||
s = "v" + str(major_ver) + "." + str(minor_ver) + "." + str(patch_ver)
|
||||
print("New version:" + s)
|
||||
return s
|
||||
|
||||
|
||||
|
||||
def lvgl_update_library_json(v):
|
||||
title("lvgl: Update version number in library.json")
|
||||
|
||||
f = open("./library.json", "r")
|
||||
|
||||
outbuf = ""
|
||||
|
||||
for i in f.read().splitlines():
|
||||
r = re.search(r'"version": ', i)
|
||||
if r:
|
||||
i = ' "version": "' + v + '",'
|
||||
|
||||
outbuf += i + '\n'
|
||||
|
||||
f.close()
|
||||
|
||||
f = open("./library.json", "w")
|
||||
|
||||
f.write(outbuf)
|
||||
f.close()
|
||||
|
||||
def lvgl_commit_push(v):
|
||||
title("lvgl: commit and push release")
|
||||
|
||||
cmd('git ci -am "Release ' + v + '"')
|
||||
cmd('git tag -a ' + v + ' -m "Release ' + v +'"')
|
||||
cmd('git push origin master')
|
||||
cmd('git push origin ' + v)
|
||||
|
||||
def lvgl_update_api_docs():
|
||||
title("lvgl: Update API with Doxygen")
|
||||
|
||||
cmd("cd scripts; doxygen");
|
||||
|
||||
|
||||
def docs_clone():
|
||||
title("docs: Clone")
|
||||
os.chdir("../")
|
||||
cmd("git clone --recursive https://github.com/littlevgl/docs.git")
|
||||
os.chdir("./docs")
|
||||
cmd("git co master")
|
||||
|
||||
def docs_get_api():
|
||||
title("docs: Get API files")
|
||||
|
||||
cmd("rm -rf xml");
|
||||
cmd("cp -r ../lvgl/docs/api_doc/xml .");
|
||||
|
||||
|
||||
def docs_update_version(v):
|
||||
title("docs: Update version number")
|
||||
|
||||
f = open("./conf.py", "r")
|
||||
|
||||
outbuf = ""
|
||||
|
||||
for i in f.read().splitlines():
|
||||
r = re.search(r'^version = ', i)
|
||||
if r:
|
||||
i = "version = '" + v + "'"
|
||||
|
||||
r = re.search(r'^release = ', i)
|
||||
if r:
|
||||
i = "version = '" + v + "'"
|
||||
|
||||
outbuf += i + '\n'
|
||||
|
||||
f.close()
|
||||
|
||||
f = open("./conf.py", "w")
|
||||
|
||||
f.write(outbuf)
|
||||
f.close()
|
||||
|
||||
def docs_update_trans():
|
||||
title("docs: Update translations")
|
||||
cmd("cd en && ./trans_push.py && ./trans_pull.py")
|
||||
|
||||
def docs_build():
|
||||
title("docs: Build")
|
||||
cmd("./build.py clean")
|
||||
|
||||
|
||||
def docs_commit_push(v):
|
||||
title("docs: Commit release")
|
||||
|
||||
cmd('git add .')
|
||||
cmd('git ci -am "Release ' + v + '"')
|
||||
cmd('git tag -a ' + v + ' -m "Release ' + v +'"')
|
||||
cmd('git push origin master')
|
||||
cmd('git push origin ' + v)
|
||||
|
||||
def clean_up():
|
||||
title("Clean up repos")
|
||||
os.chdir("..")
|
||||
cmd("rm -rf lvgl docs")
|
||||
|
||||
lvgl_clone()
|
||||
lvgl_update_api_docs()
|
||||
ver_str = lvgl_update_version()
|
||||
lvgl_update_library_json(ver_str)
|
||||
lvgl_commit_push(ver_str)
|
||||
|
||||
docs_clone()
|
||||
docs_get_api()
|
||||
docs_update_version(ver_str)
|
||||
docs_update_trans()
|
||||
docs_build()
|
||||
docs_commit_push(ver_str)
|
||||
|
||||
clean_up()
|
||||
|
||||
112
src/lv_api_map.h
112
src/lv_api_map.h
@@ -30,12 +30,19 @@ extern "C" {
|
||||
/*---------------------
|
||||
* V6.0 COMPATIBILITY
|
||||
*--------------------*/
|
||||
#if LV_USE_API_EXTENSION_V6
|
||||
|
||||
static inline void lv_task_once(lv_task_t *task)
|
||||
static inline void lv_task_once(lv_task_t * task)
|
||||
{
|
||||
lv_task_set_repeat_count(task, 1);
|
||||
}
|
||||
|
||||
#if LV_USE_CHECKBOX
|
||||
|
||||
#define lv_checkbox_set_static_text lv_checkbox_set_text_static
|
||||
|
||||
#endif
|
||||
|
||||
#if LV_USE_CHART
|
||||
|
||||
#define lv_chart_get_point_cnt lv_chart_get_point_count
|
||||
@@ -57,6 +64,8 @@ static inline bool lv_dropdown_get_draw_arrow(lv_obj_t * ddlist)
|
||||
else return false;
|
||||
}
|
||||
|
||||
#define lv_dropdown_set_static_options lv_dropdown_set_options_static
|
||||
|
||||
#endif
|
||||
|
||||
#if LV_USE_BAR
|
||||
@@ -89,6 +98,12 @@ static inline bool lv_bar_get_sym(lv_obj_t * bar)
|
||||
|
||||
#endif
|
||||
|
||||
#if LV_USE_LABEL
|
||||
|
||||
#define lv_label_set_static_text lv_label_set_text_static
|
||||
|
||||
#endif
|
||||
|
||||
#if LV_USE_SLIDER
|
||||
|
||||
/**
|
||||
@@ -116,6 +131,101 @@ static inline bool lv_slider_get_sym(lv_obj_t * slider)
|
||||
|
||||
#endif
|
||||
|
||||
#if LV_USE_ROLLER
|
||||
|
||||
/**
|
||||
* Set a fixed width for the roller.
|
||||
* @param roller pointer to a roller object
|
||||
* @param w width
|
||||
* @deprecated As of v7.0, you should use `lv_roller_set_auto_fit` and set the width normally instead.
|
||||
*/
|
||||
static inline void lv_roller_set_fix_width(lv_obj_t * roller, lv_coord_t w)
|
||||
{
|
||||
lv_roller_set_auto_fit(roller, false);
|
||||
lv_obj_set_width(roller, w);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if LV_USE_PAGE
|
||||
#define lv_scrlbar_mode_t lv_scrollbar_mode_t
|
||||
|
||||
#define LV_SCRLBAR_MODE_OFF LV_SCROLLBAR_MODE_OFF
|
||||
#define LV_SCRLBAR_MODE_ON LV_SCROLLBAR_MODE_ON
|
||||
#define LV_SCRLBAR_MODE_DRAG LV_SCROLLBAR_MODE_DRAG
|
||||
#define LV_SCRLBAR_MODE_AUTO LV_SCROLLBAR_MODE_AUTO
|
||||
#define LV_SCRLBAR_MODE_HIDE LV_SCROLLBAR_MODE_HIDE
|
||||
#define LV_SCRLBAR_MODE_UNHIDE LV_SCROLLBAR_MODE_UNHIDE
|
||||
|
||||
|
||||
static inline void lv_page_set_scrlbar_mode(lv_obj_t * page, lv_scrlbar_mode_t sb_mode)
|
||||
{
|
||||
lv_page_set_scrollbar_mode(page, sb_mode);
|
||||
}
|
||||
static inline lv_scrollbar_mode_t lv_page_get_scrlbar_mode(lv_obj_t * page)
|
||||
{
|
||||
return lv_page_get_scrollbar_mode(page);
|
||||
}
|
||||
|
||||
|
||||
static inline lv_obj_t * lv_page_get_scrl(lv_obj_t * page)
|
||||
{
|
||||
return lv_page_get_scrollable(page);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*LV_USE_API_EXTENSION_V6*/
|
||||
|
||||
|
||||
|
||||
|
||||
/*---------------------
|
||||
* V7.0 COMPATIBILITY
|
||||
*--------------------*/
|
||||
#if LV_USE_API_EXTENSION_V7
|
||||
#if LV_USE_WIN
|
||||
|
||||
static inline lv_obj_t * lv_win_add_btn(lv_obj_t * win, const void * img_src)
|
||||
{
|
||||
return lv_win_add_btn_right(win, img_src);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if LV_USE_CHART
|
||||
static inline void lv_chart_set_range(lv_obj_t * chart, lv_coord_t ymin, lv_coord_t ymax)
|
||||
{
|
||||
lv_chart_set_y_range(chart, LV_CHART_AXIS_PRIMARY_Y, ymin, ymax);
|
||||
}
|
||||
|
||||
|
||||
static inline void lv_chart_clear_serie(lv_obj_t * chart, lv_chart_series_t * series)
|
||||
{
|
||||
lv_chart_clear_series(chart, series);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static inline void lv_obj_align_origo(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_ofs,
|
||||
lv_coord_t y_ofs)
|
||||
{
|
||||
lv_obj_align_mid(obj, base, align, x_ofs, y_ofs);
|
||||
}
|
||||
|
||||
static inline void lv_obj_align_origo_x(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_ofs)
|
||||
{
|
||||
lv_obj_align_mid_y(obj, base, align, x_ofs);
|
||||
}
|
||||
|
||||
static inline void lv_obj_align_origo_y(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t y_ofs)
|
||||
{
|
||||
lv_obj_align_mid_y(obj, base, align, y_ofs);
|
||||
}
|
||||
|
||||
#endif /*LV_USE_API_EXTENSION_V6*/
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
/* Color depth:
|
||||
* - 1: 1 byte per pixel
|
||||
* - 8: RGB233
|
||||
* - 8: RGB332
|
||||
* - 16: RGB565
|
||||
* - 32: ARGB8888
|
||||
*/
|
||||
@@ -66,11 +66,6 @@
|
||||
#define LV_COLOR_TRANSP LV_COLOR_LIME /*LV_COLOR_LIME: pure green*/
|
||||
#endif
|
||||
|
||||
/* Enable chroma keying for indexed images. */
|
||||
#ifndef LV_INDEXED_CHROMA
|
||||
#define LV_INDEXED_CHROMA 1
|
||||
#endif
|
||||
|
||||
/* Enable anti-aliasing (lines, and radiuses will be smoothed) */
|
||||
#ifndef LV_ANTIALIAS
|
||||
#define LV_ANTIALIAS 1
|
||||
@@ -152,6 +147,12 @@
|
||||
#endif
|
||||
#endif /*LV_MEM_CUSTOM*/
|
||||
|
||||
/* Use the standard memcpy and memset instead of LVGL's own functions.
|
||||
* The standard functions might or might not be faster depending on their implementation. */
|
||||
#ifndef LV_MEMCPY_MEMSET_STD
|
||||
#define LV_MEMCPY_MEMSET_STD 0
|
||||
#endif
|
||||
|
||||
/* Garbage Collector settings
|
||||
* Used if lvgl is binded to higher level language and the memory is managed by that language */
|
||||
#ifndef LV_ENABLE_GC
|
||||
@@ -188,7 +189,7 @@
|
||||
|
||||
/* Drag throw slow-down in [%]. Greater value -> faster slow-down */
|
||||
#ifndef LV_INDEV_DEF_DRAG_THROW
|
||||
#define LV_INDEV_DEF_DRAG_THROW 20
|
||||
#define LV_INDEV_DEF_DRAG_THROW 10
|
||||
#endif
|
||||
|
||||
/* Long press time in milliseconds.
|
||||
@@ -228,7 +229,7 @@
|
||||
|
||||
#endif
|
||||
|
||||
/* 1: Enable shadow drawing*/
|
||||
/* 1: Enable shadow drawing on rectangles*/
|
||||
#ifndef LV_USE_SHADOW
|
||||
#define LV_USE_SHADOW 1
|
||||
#endif
|
||||
@@ -242,6 +243,21 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*1: enable outline drawing on rectangles*/
|
||||
#ifndef LV_USE_OUTLINE
|
||||
#define LV_USE_OUTLINE 1
|
||||
#endif
|
||||
|
||||
/*1: enable pattern drawing on rectangles*/
|
||||
#ifndef LV_USE_PATTERN
|
||||
#define LV_USE_PATTERN 1
|
||||
#endif
|
||||
|
||||
/*1: enable value string drawing on rectangles*/
|
||||
#ifndef LV_USE_VALUE_STR
|
||||
#define LV_USE_VALUE_STR 1
|
||||
#endif
|
||||
|
||||
/* 1: Use other blend modes than normal (`LV_BLEND_MODE_...`)*/
|
||||
#ifndef LV_USE_BLEND_MODES
|
||||
#define LV_USE_BLEND_MODES 1
|
||||
@@ -252,6 +268,11 @@
|
||||
#define LV_USE_OPA_SCALE 1
|
||||
#endif
|
||||
|
||||
/* 1: Use image zoom and rotation*/
|
||||
#ifndef LV_USE_IMG_TRANSFORM
|
||||
#define LV_USE_IMG_TRANSFORM 1
|
||||
#endif
|
||||
|
||||
/* 1: Enable object groups (for keyboard/encoder navigation) */
|
||||
#ifndef LV_USE_GROUP
|
||||
#define LV_USE_GROUP 1
|
||||
@@ -261,11 +282,16 @@
|
||||
|
||||
/* 1: Enable GPU interface*/
|
||||
#ifndef LV_USE_GPU
|
||||
#define LV_USE_GPU 1
|
||||
#define LV_USE_GPU 1 /*Only enables `gpu_fill_cb` and `gpu_blend_cb` in the disp. drv- */
|
||||
#endif
|
||||
#ifndef LV_USE_GPU_STM32_DMA2D
|
||||
#define LV_USE_GPU_STM32_DMA2D 0
|
||||
#endif
|
||||
/*If enabling LV_USE_GPU_STM32_DMA2D, LV_GPU_DMA2D_CMSIS_INCLUDE must be defined to include path of CMSIS header of target processor
|
||||
e.g. "stm32f769xx.h" or "stm32f429xx.h" */
|
||||
#ifndef LV_GPU_DMA2D_CMSIS_INCLUDE
|
||||
#define LV_GPU_DMA2D_CMSIS_INCLUDE
|
||||
#endif
|
||||
|
||||
/* 1: Enable file system (might be required for images */
|
||||
#ifndef LV_USE_FILESYSTEM
|
||||
@@ -285,6 +311,14 @@
|
||||
#define LV_USE_PERF_MONITOR 0
|
||||
#endif
|
||||
|
||||
/*1: Use the functions and types from the older API if possible */
|
||||
#ifndef LV_USE_API_EXTENSION_V6
|
||||
#define LV_USE_API_EXTENSION_V6 1
|
||||
#endif
|
||||
#ifndef LV_USE_API_EXTENSION_V7
|
||||
#define LV_USE_API_EXTENSION_V7 1
|
||||
#endif
|
||||
|
||||
/*========================
|
||||
* Image decoder and cache
|
||||
*========================*/
|
||||
@@ -314,6 +348,12 @@
|
||||
/*=====================
|
||||
* Compiler settings
|
||||
*====================*/
|
||||
|
||||
/* For big endian systems set to 1 */
|
||||
#ifndef LV_BIG_ENDIAN_SYSTEM
|
||||
#define LV_BIG_ENDIAN_SYSTEM 0
|
||||
#endif
|
||||
|
||||
/* Define a custom attribute to `lv_tick_inc` function */
|
||||
#ifndef LV_ATTRIBUTE_TICK_INC
|
||||
#define LV_ATTRIBUTE_TICK_INC
|
||||
@@ -358,6 +398,12 @@
|
||||
#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning
|
||||
#endif
|
||||
|
||||
/* Prefix variables that are used in GPU accelerated operations, often these need to be
|
||||
* placed in RAM sections that are DMA accessible */
|
||||
#ifndef LV_ATTRIBUTE_DMA
|
||||
#define LV_ATTRIBUTE_DMA
|
||||
#endif
|
||||
|
||||
/*===================
|
||||
* HAL settings
|
||||
*==================*/
|
||||
@@ -369,10 +415,10 @@
|
||||
#endif
|
||||
#if LV_TICK_CUSTOM == 1
|
||||
#ifndef LV_TICK_CUSTOM_INCLUDE
|
||||
#define LV_TICK_CUSTOM_INCLUDE "something.h" /*Header for the sys time function*/
|
||||
#define LV_TICK_CUSTOM_INCLUDE "Arduino.h" /*Header for the system time function*/
|
||||
#endif
|
||||
#ifndef LV_TICK_CUSTOM_SYS_TIME_EXPR
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current systime in ms*/
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current system time in ms*/
|
||||
#endif
|
||||
#endif /*LV_TICK_CUSTOM*/
|
||||
|
||||
@@ -463,8 +509,8 @@
|
||||
|
||||
/* The built-in fonts contains the ASCII range and some Symbols with 4 bit-per-pixel.
|
||||
* The symbols are available via `LV_SYMBOL_...` defines
|
||||
* More info about fonts: https://docs.littlevgl.com/#Fonts
|
||||
* To create a new font go to: https://littlevgl.com/ttf-font-to-c-array
|
||||
* More info about fonts: https://docs.lvgl.io/v7/en/html/overview/font.html
|
||||
* To create a new font go to: https://lvgl.com/ttf-font-to-c-array
|
||||
*/
|
||||
|
||||
/* Montserrat fonts with bpp = 4
|
||||
@@ -473,10 +519,10 @@
|
||||
#define LV_FONT_MONTSERRAT_12 0
|
||||
#endif
|
||||
#ifndef LV_FONT_MONTSERRAT_14
|
||||
#define LV_FONT_MONTSERRAT_14 0
|
||||
#define LV_FONT_MONTSERRAT_14 1
|
||||
#endif
|
||||
#ifndef LV_FONT_MONTSERRAT_16
|
||||
#define LV_FONT_MONTSERRAT_16 1
|
||||
#define LV_FONT_MONTSERRAT_16 0
|
||||
#endif
|
||||
#ifndef LV_FONT_MONTSERRAT_18
|
||||
#define LV_FONT_MONTSERRAT_18 0
|
||||
@@ -564,6 +610,18 @@
|
||||
#define LV_FONT_FMT_TXT_LARGE 0
|
||||
#endif
|
||||
|
||||
/* Enables/disables support for compressed fonts. If it's disabled, compressed
|
||||
* glyphs cannot be processed by the library and won't be rendered.
|
||||
*/
|
||||
#ifndef LV_USE_FONT_COMPRESSED
|
||||
#define LV_USE_FONT_COMPRESSED 1
|
||||
#endif
|
||||
|
||||
/* Enable subpixel rendering */
|
||||
#ifndef LV_USE_FONT_SUBPX
|
||||
#define LV_USE_FONT_SUBPX 1
|
||||
#endif
|
||||
#if LV_USE_FONT_SUBPX
|
||||
/* Set the pixel order of the display.
|
||||
* Important only if "subpx fonts" are used.
|
||||
* With "normal" font it doesn't matter.
|
||||
@@ -571,6 +629,7 @@
|
||||
#ifndef LV_FONT_SUBPX_BGR
|
||||
#define LV_FONT_SUBPX_BGR 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Declare the type of the user data of fonts (can be e.g. `void *`, `int`, `struct`)*/
|
||||
|
||||
@@ -579,17 +638,37 @@
|
||||
*================*/
|
||||
|
||||
/*Always enable at least on theme*/
|
||||
|
||||
/* No theme, you can apply your styles as you need
|
||||
* No flags. Set LV_THEME_DEFAULT_FLAG 0 */
|
||||
#ifndef LV_USE_THEME_EMPTY
|
||||
#define LV_USE_THEME_EMPTY 0 /*No theme, you can apply your styles as you need*/
|
||||
#define LV_USE_THEME_EMPTY 1
|
||||
#endif
|
||||
|
||||
/*Simple to the create your theme based on it
|
||||
* No flags. Set LV_THEME_DEFAULT_FLAG 0 */
|
||||
#ifndef LV_USE_THEME_TEMPLATE
|
||||
#define LV_USE_THEME_TEMPLATE 0 /*Simple to the create your theme based on it*/
|
||||
#define LV_USE_THEME_TEMPLATE 1
|
||||
#endif
|
||||
|
||||
/* A fast and impressive theme.
|
||||
* Flags:
|
||||
* LV_THEME_MATERIAL_FLAG_LIGHT: light theme
|
||||
* LV_THEME_MATERIAL_FLAG_DARK: dark theme
|
||||
* LV_THEME_MATERIAL_FLAG_NO_TRANSITION: disable transitions (state change animations)
|
||||
* LV_THEME_MATERIAL_FLAG_NO_FOCUS: disable indication of focused state)
|
||||
* */
|
||||
#ifndef LV_USE_THEME_MATERIAL
|
||||
#define LV_USE_THEME_MATERIAL 1 /*A fast and impressive theme*/
|
||||
#define LV_USE_THEME_MATERIAL 1
|
||||
#endif
|
||||
|
||||
/* Mono-color theme for monochrome displays.
|
||||
* If LV_THEME_DEFAULT_COLOR_PRIMARY is LV_COLOR_BLACK the
|
||||
* texts and borders will be black and the background will be
|
||||
* white. Else the colors are inverted.
|
||||
* No flags. Set LV_THEME_DEFAULT_FLAG 0 */
|
||||
#ifndef LV_USE_THEME_MONO
|
||||
#define LV_USE_THEME_MONO 0 /*Mono-color theme for monochrome displays*/
|
||||
#define LV_USE_THEME_MONO 1
|
||||
#endif
|
||||
|
||||
#ifndef LV_THEME_DEFAULT_INCLUDE
|
||||
@@ -599,25 +678,25 @@
|
||||
#define LV_THEME_DEFAULT_INIT lv_theme_material_init
|
||||
#endif
|
||||
#ifndef LV_THEME_DEFAULT_COLOR_PRIMARY
|
||||
#define LV_THEME_DEFAULT_COLOR_PRIMARY LV_COLOR_RED
|
||||
#define LV_THEME_DEFAULT_COLOR_PRIMARY lv_color_hex(0x01a2b1)
|
||||
#endif
|
||||
#ifndef LV_THEME_DEFAULT_COLOR_SECONDARY
|
||||
#define LV_THEME_DEFAULT_COLOR_SECONDARY LV_COLOR_BLUE
|
||||
#define LV_THEME_DEFAULT_COLOR_SECONDARY lv_color_hex(0x44d1b6)
|
||||
#endif
|
||||
#ifndef LV_THEME_DEFAULT_FLAG
|
||||
#define LV_THEME_DEFAULT_FLAG LV_THEME_MATERIAL_FLAG_LIGHT
|
||||
#endif
|
||||
#ifndef LV_THEME_DEFAULT_FONT_SMALL
|
||||
#define LV_THEME_DEFAULT_FONT_SMALL &lv_font_montserrat_16
|
||||
#define LV_THEME_DEFAULT_FONT_SMALL &lv_font_montserrat_14
|
||||
#endif
|
||||
#ifndef LV_THEME_DEFAULT_FONT_NORMAL
|
||||
#define LV_THEME_DEFAULT_FONT_NORMAL &lv_font_montserrat_16
|
||||
#define LV_THEME_DEFAULT_FONT_NORMAL &lv_font_montserrat_14
|
||||
#endif
|
||||
#ifndef LV_THEME_DEFAULT_FONT_SUBTITLE
|
||||
#define LV_THEME_DEFAULT_FONT_SUBTITLE &lv_font_montserrat_16
|
||||
#define LV_THEME_DEFAULT_FONT_SUBTITLE &lv_font_montserrat_14
|
||||
#endif
|
||||
#ifndef LV_THEME_DEFAULT_FONT_TITLE
|
||||
#define LV_THEME_DEFAULT_FONT_TITLE &lv_font_montserrat_16
|
||||
#define LV_THEME_DEFAULT_FONT_TITLE &lv_font_montserrat_14
|
||||
#endif
|
||||
|
||||
/*=================
|
||||
@@ -699,6 +778,10 @@
|
||||
#ifndef lv_vsnprintf
|
||||
# define lv_vsnprintf vsnprintf
|
||||
#endif
|
||||
#else /*!LV_SPRINTF_CUSTOM*/
|
||||
#ifndef LV_SPRINTF_DISABLE_FLOAT
|
||||
# define LV_SPRINTF_DISABLE_FLOAT 1
|
||||
#endif
|
||||
#endif /*LV_SPRINTF_CUSTOM*/
|
||||
|
||||
/*===================
|
||||
@@ -722,7 +805,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*1: enable `lv_obj_realaign()` based on `lv_obj_align()` parameters*/
|
||||
/*1: enable `lv_obj_realign()` based on `lv_obj_align()` parameters*/
|
||||
#ifndef LV_USE_OBJ_REALIGN
|
||||
#define LV_USE_OBJ_REALIGN 1
|
||||
#endif
|
||||
@@ -740,7 +823,7 @@
|
||||
* LV OBJ X USAGE
|
||||
*================*/
|
||||
/*
|
||||
* Documentation of the object types: https://docs.littlevgl.com/#Object-types
|
||||
* Documentation of the object types: https://docs.lvgl.com/#Object-types
|
||||
*/
|
||||
|
||||
/*Arc (dependencies: -)*/
|
||||
@@ -757,12 +840,6 @@
|
||||
#ifndef LV_USE_BTN
|
||||
#define LV_USE_BTN 1
|
||||
#endif
|
||||
#if LV_USE_BTN != 0
|
||||
/*Enable button-state animations - draw a circle on click (dependencies: LV_USE_ANIMATION)*/
|
||||
#ifndef LV_BTN_INK_EFFECT
|
||||
# define LV_BTN_INK_EFFECT 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Button matrix (dependencies: -)*/
|
||||
#ifndef LV_USE_BTNMATRIX
|
||||
@@ -773,6 +850,11 @@
|
||||
#ifndef LV_USE_CALENDAR
|
||||
#define LV_USE_CALENDAR 1
|
||||
#endif
|
||||
#if LV_USE_CALENDAR
|
||||
#ifndef LV_CALENDAR_WEEK_STARTS_MONDAY
|
||||
# define LV_CALENDAR_WEEK_STARTS_MONDAY 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Canvas (dependencies: lv_img)*/
|
||||
#ifndef LV_USE_CANVAS
|
||||
@@ -914,7 +996,7 @@
|
||||
|
||||
/*Mask (dependencies: -)*/
|
||||
#ifndef LV_USE_OBJMASK
|
||||
#define LV_USE_OBJMASK 0
|
||||
#define LV_USE_OBJMASK 1
|
||||
#endif
|
||||
|
||||
/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/
|
||||
@@ -965,6 +1047,11 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Rotary (dependencies: lv_arc, lv_btn)*/
|
||||
#ifndef LV_USE_ROTARY
|
||||
#define LV_USE_ROTARY 1
|
||||
#endif
|
||||
|
||||
/*Slider (dependencies: lv_bar)*/
|
||||
#ifndef LV_USE_SLIDER
|
||||
#define LV_USE_SLIDER 1
|
||||
|
||||
@@ -4,7 +4,6 @@ CSRCS += lv_disp.c
|
||||
CSRCS += lv_obj.c
|
||||
CSRCS += lv_refr.c
|
||||
CSRCS += lv_style.c
|
||||
CSRCS += lv_debug.c
|
||||
|
||||
DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/lv_core
|
||||
VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/lv_core
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
*********************/
|
||||
#include "lv_disp.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
#include "../lv_core/lv_refr.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -21,6 +22,12 @@
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
static void scr_load_anim_start(lv_anim_t * a);
|
||||
static void opa_scale_anim(lv_obj_t * obj, lv_anim_value_t v);
|
||||
static void scr_anim_ready(lv_anim_t * a);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
@@ -43,13 +50,30 @@ lv_obj_t * lv_disp_get_scr_act(lv_disp_t * disp)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("lv_scr_act: no display registered to get its act. screen");
|
||||
LV_LOG_WARN("no display registered to get its active screen");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return disp->act_scr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return with a pointer to the previous screen. Only used during screen transitions.
|
||||
* @param disp pointer to display which previous screen should be get. (NULL to use the default
|
||||
* screen)
|
||||
* @return pointer to the previous screen object or NULL if not used now
|
||||
*/
|
||||
lv_obj_t * lv_disp_get_scr_prev(lv_disp_t * disp)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("no display registered to get its previous screen");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return disp->prev_scr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a screen active
|
||||
* @param scr pointer to a screen
|
||||
@@ -96,6 +120,7 @@ lv_obj_t * lv_disp_get_layer_sys(lv_disp_t * disp)
|
||||
return disp->sys_layer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Assign a screen to a display.
|
||||
* @param disp pointer to a display where to assign the screen
|
||||
@@ -112,26 +137,179 @@ void lv_disp_assign_screen(lv_disp_t * disp, lv_obj_t * scr)
|
||||
|
||||
if(old_disp == disp) return;
|
||||
|
||||
lv_ll_chg_list(&old_disp->scr_ll, &disp->scr_ll, scr, true);
|
||||
_lv_ll_chg_list(&old_disp->scr_ll, &disp->scr_ll, scr, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a pointer to the screen refresher task to
|
||||
* modify its parameters with `lv_task_...` functions.
|
||||
* Set the background color of a display
|
||||
* @param disp pointer to a display
|
||||
* @return pointer to the display refresher task. (NULL on error)
|
||||
* @param color color of the background
|
||||
*/
|
||||
lv_task_t * lv_disp_get_refr_task(lv_disp_t * disp)
|
||||
void lv_disp_set_bg_color(lv_disp_t * disp, lv_color_t color)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("lv_disp_get_refr_task: no display registered");
|
||||
return NULL;
|
||||
LV_LOG_WARN("no display registered");
|
||||
return;
|
||||
}
|
||||
|
||||
return disp->refr_task;
|
||||
disp->bg_color = color;
|
||||
|
||||
lv_area_t a;
|
||||
lv_area_set(&a, 0, 0, lv_disp_get_hor_res(disp) - 1, lv_disp_get_ver_res(disp) - 1);
|
||||
_lv_inv_area(disp, &a);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the background image of a display
|
||||
* @param disp pointer to a display
|
||||
* @param img_src path to file or pointer to an `lv_img_dsc_t` variable
|
||||
*/
|
||||
void lv_disp_set_bg_image(lv_disp_t * disp, const void * img_src)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("no display registered");
|
||||
return;
|
||||
}
|
||||
|
||||
disp->bg_img = img_src;
|
||||
|
||||
lv_area_t a;
|
||||
lv_area_set(&a, 0, 0, lv_disp_get_hor_res(disp) - 1, lv_disp_get_ver_res(disp) - 1);
|
||||
_lv_inv_area(disp, &a);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Opacity of the background
|
||||
* @param disp pointer to a display
|
||||
* @param opa opacity (0..255)
|
||||
*/
|
||||
void lv_disp_set_bg_opa(lv_disp_t * disp, lv_opa_t opa)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("no display registered");
|
||||
return;
|
||||
}
|
||||
|
||||
disp->bg_opa = opa;
|
||||
|
||||
lv_area_t a;
|
||||
lv_area_set(&a, 0, 0, lv_disp_get_hor_res(disp) - 1, lv_disp_get_ver_res(disp) - 1);
|
||||
_lv_inv_area(disp, &a);
|
||||
}
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
|
||||
/**
|
||||
* Switch screen with animation
|
||||
* @param scr pointer to the new screen to load
|
||||
* @param anim_type type of the animation from `lv_scr_load_anim_t`. E.g. `LV_SCR_LOAD_ANIM_MOVE_LEFT`
|
||||
* @param time time of the animation
|
||||
* @param delay delay before the transition
|
||||
* @param auto_del true: automatically delete the old screen
|
||||
*/
|
||||
void lv_scr_load_anim(lv_obj_t * new_scr, lv_scr_load_anim_t anim_type, uint32_t time, uint32_t delay, bool auto_del)
|
||||
{
|
||||
lv_disp_t * d = lv_obj_get_disp(new_scr);
|
||||
|
||||
if(d->prev_scr && d->del_prev) {
|
||||
lv_obj_del(d->prev_scr);
|
||||
d->prev_scr = NULL;
|
||||
}
|
||||
|
||||
d->del_prev = auto_del;
|
||||
|
||||
/*Be sure there is no other animation on the screens*/
|
||||
lv_anim_del(new_scr, NULL);
|
||||
lv_anim_del(lv_scr_act(), NULL);
|
||||
|
||||
/*Be sure both screens are in a normal position*/
|
||||
lv_obj_set_pos(new_scr, 0, 0);
|
||||
lv_obj_set_pos(lv_scr_act(), 0, 0);
|
||||
lv_style_remove_prop(lv_obj_get_local_style(new_scr, LV_OBJ_PART_MAIN), LV_STYLE_OPA_SCALE);
|
||||
lv_style_remove_prop(lv_obj_get_local_style(lv_scr_act(), LV_OBJ_PART_MAIN), LV_STYLE_OPA_SCALE);
|
||||
|
||||
lv_anim_t a_new;
|
||||
lv_anim_init(&a_new);
|
||||
lv_anim_set_var(&a_new, new_scr);
|
||||
lv_anim_set_start_cb(&a_new, scr_load_anim_start);
|
||||
lv_anim_set_ready_cb(&a_new, scr_anim_ready);
|
||||
lv_anim_set_time(&a_new, time);
|
||||
lv_anim_set_delay(&a_new, delay);
|
||||
|
||||
lv_anim_t a_old;
|
||||
lv_anim_init(&a_old);
|
||||
lv_anim_set_var(&a_old, d->act_scr);
|
||||
lv_anim_set_time(&a_old, time);
|
||||
lv_anim_set_delay(&a_old, delay);
|
||||
|
||||
switch(anim_type) {
|
||||
case LV_SCR_LOAD_ANIM_NONE:
|
||||
/* Create a dummy animation to apply the delay*/
|
||||
lv_anim_set_exec_cb(&a_new, (lv_anim_exec_xcb_t) lv_obj_set_x);
|
||||
lv_anim_set_values(&a_new, 0, 0);
|
||||
break;
|
||||
case LV_SCR_LOAD_ANIM_OVER_LEFT:
|
||||
lv_anim_set_exec_cb(&a_new, (lv_anim_exec_xcb_t) lv_obj_set_x);
|
||||
lv_anim_set_values(&a_new, lv_disp_get_hor_res(d), 0);
|
||||
break;
|
||||
case LV_SCR_LOAD_ANIM_OVER_RIGHT:
|
||||
lv_anim_set_exec_cb(&a_new, (lv_anim_exec_xcb_t) lv_obj_set_x);
|
||||
lv_anim_set_values(&a_new, -lv_disp_get_hor_res(d), 0);
|
||||
break;
|
||||
case LV_SCR_LOAD_ANIM_OVER_TOP:
|
||||
lv_anim_set_exec_cb(&a_new, (lv_anim_exec_xcb_t) lv_obj_set_y);
|
||||
lv_anim_set_values(&a_new, lv_disp_get_ver_res(d), 0);
|
||||
break;
|
||||
case LV_SCR_LOAD_ANIM_OVER_BOTTOM:
|
||||
lv_anim_set_exec_cb(&a_new, (lv_anim_exec_xcb_t) lv_obj_set_y);
|
||||
lv_anim_set_values(&a_new, -lv_disp_get_ver_res(d), 0);
|
||||
break;
|
||||
case LV_SCR_LOAD_ANIM_MOVE_LEFT:
|
||||
lv_anim_set_exec_cb(&a_new, (lv_anim_exec_xcb_t) lv_obj_set_x);
|
||||
lv_anim_set_values(&a_new, lv_disp_get_hor_res(d), 0);
|
||||
|
||||
lv_anim_set_exec_cb(&a_old, (lv_anim_exec_xcb_t) lv_obj_set_x);
|
||||
lv_anim_set_values(&a_old, 0, -lv_disp_get_hor_res(d));
|
||||
break;
|
||||
case LV_SCR_LOAD_ANIM_MOVE_RIGHT:
|
||||
lv_anim_set_exec_cb(&a_new, (lv_anim_exec_xcb_t) lv_obj_set_x);
|
||||
lv_anim_set_values(&a_new, -lv_disp_get_hor_res(d), 0);
|
||||
|
||||
lv_anim_set_exec_cb(&a_old, (lv_anim_exec_xcb_t) lv_obj_set_x);
|
||||
lv_anim_set_values(&a_old, 0, lv_disp_get_hor_res(d));
|
||||
break;
|
||||
case LV_SCR_LOAD_ANIM_MOVE_TOP:
|
||||
lv_anim_set_exec_cb(&a_new, (lv_anim_exec_xcb_t) lv_obj_set_y);
|
||||
lv_anim_set_values(&a_new, lv_disp_get_ver_res(d), 0);
|
||||
|
||||
lv_anim_set_exec_cb(&a_old, (lv_anim_exec_xcb_t) lv_obj_set_y);
|
||||
lv_anim_set_values(&a_old, 0, -lv_disp_get_ver_res(d));
|
||||
break;
|
||||
case LV_SCR_LOAD_ANIM_MOVE_BOTTOM:
|
||||
lv_anim_set_exec_cb(&a_new, (lv_anim_exec_xcb_t) lv_obj_set_y);
|
||||
lv_anim_set_values(&a_new, -lv_disp_get_ver_res(d), 0);
|
||||
|
||||
lv_anim_set_exec_cb(&a_old, (lv_anim_exec_xcb_t) lv_obj_set_y);
|
||||
lv_anim_set_values(&a_old, 0, lv_disp_get_ver_res(d));
|
||||
break;
|
||||
|
||||
case LV_SCR_LOAD_ANIM_FADE_ON:
|
||||
lv_anim_set_exec_cb(&a_new, (lv_anim_exec_xcb_t) opa_scale_anim);
|
||||
lv_anim_set_values(&a_new, LV_OPA_TRANSP, LV_OPA_COVER);
|
||||
break;
|
||||
}
|
||||
|
||||
lv_anim_start(&a_new);
|
||||
lv_anim_start(&a_old);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get elapsed time since last user activity on a display (e.g. click)
|
||||
* @param disp pointer to an display (NULL to get the overall smallest inactivity)
|
||||
@@ -174,6 +352,49 @@ void lv_disp_trig_activity(lv_disp_t * disp)
|
||||
disp->last_activity_time = lv_tick_get();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a pointer to the screen refresher task to
|
||||
* modify its parameters with `lv_task_...` functions.
|
||||
* @param disp pointer to a display
|
||||
* @return pointer to the display refresher task. (NULL on error)
|
||||
*/
|
||||
lv_task_t * _lv_disp_get_refr_task(lv_disp_t * disp)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("lv_disp_get_refr_task: no display registered");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return disp->refr_task;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
static void scr_load_anim_start(lv_anim_t * a)
|
||||
{
|
||||
lv_disp_t * d = lv_obj_get_disp(a->var);
|
||||
d->prev_scr = lv_scr_act();
|
||||
|
||||
lv_disp_load_scr(a->var);
|
||||
}
|
||||
|
||||
static void opa_scale_anim(lv_obj_t * obj, lv_anim_value_t v)
|
||||
{
|
||||
lv_obj_set_style_local_opa_scale(obj, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, v);
|
||||
}
|
||||
|
||||
|
||||
static void scr_anim_ready(lv_anim_t * a)
|
||||
{
|
||||
lv_disp_t * d = lv_obj_get_disp(a->var);
|
||||
|
||||
if(d->prev_scr && d->del_prev) lv_obj_del(d->prev_scr);
|
||||
d->prev_scr = NULL;
|
||||
lv_style_remove_prop(lv_obj_get_local_style(a->var, LV_OBJ_PART_MAIN), LV_STYLE_OPA_SCALE);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -24,6 +24,19 @@ extern "C" {
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef enum {
|
||||
LV_SCR_LOAD_ANIM_NONE,
|
||||
LV_SCR_LOAD_ANIM_OVER_LEFT,
|
||||
LV_SCR_LOAD_ANIM_OVER_RIGHT,
|
||||
LV_SCR_LOAD_ANIM_OVER_TOP,
|
||||
LV_SCR_LOAD_ANIM_OVER_BOTTOM,
|
||||
LV_SCR_LOAD_ANIM_MOVE_LEFT,
|
||||
LV_SCR_LOAD_ANIM_MOVE_RIGHT,
|
||||
LV_SCR_LOAD_ANIM_MOVE_TOP,
|
||||
LV_SCR_LOAD_ANIM_MOVE_BOTTOM,
|
||||
LV_SCR_LOAD_ANIM_FADE_ON,
|
||||
} lv_scr_load_anim_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
@@ -36,6 +49,14 @@ extern "C" {
|
||||
*/
|
||||
lv_obj_t * lv_disp_get_scr_act(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Return with a pointer to the previous screen. Only used during screen transitions.
|
||||
* @param disp pointer to display which previous screen should be get. (NULL to use the default
|
||||
* screen)
|
||||
* @return pointer to the previous screen object or NULL if not used now
|
||||
*/
|
||||
lv_obj_t * lv_disp_get_scr_prev(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Make a screen active
|
||||
* @param scr pointer to a screen
|
||||
@@ -64,14 +85,41 @@ lv_obj_t * lv_disp_get_layer_sys(lv_disp_t * disp);
|
||||
*/
|
||||
void lv_disp_assign_screen(lv_disp_t * disp, lv_obj_t * scr);
|
||||
|
||||
/**
|
||||
* Get a pointer to the screen refresher task to
|
||||
* modify its parameters with `lv_task_...` functions.
|
||||
* @param disp pointer to a display
|
||||
* @return pointer to the display refresher task. (NULL on error)
|
||||
*/
|
||||
lv_task_t * lv_disp_get_refr_task(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Set the background color of a display
|
||||
* @param disp pointer to a display
|
||||
* @param color color of the background
|
||||
*/
|
||||
void lv_disp_set_bg_color(lv_disp_t * disp, lv_color_t color);
|
||||
|
||||
/**
|
||||
* Set the background image of a display
|
||||
* @param disp pointer to a display
|
||||
* @param img_src path to file or pointer to an `lv_img_dsc_t` variable
|
||||
*/
|
||||
void lv_disp_set_bg_image(lv_disp_t * disp, const void * img_src);
|
||||
|
||||
/**
|
||||
* Opacity of the background
|
||||
* @param disp pointer to a display
|
||||
* @param opa opacity (0..255)
|
||||
*/
|
||||
void lv_disp_set_bg_opa(lv_disp_t * disp, lv_opa_t opa);
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
|
||||
/**
|
||||
* Switch screen with animation
|
||||
* @param scr pointer to the new screen to load
|
||||
* @param anim_type type of the animation from `lv_scr_load_anim_t`. E.g. `LV_SCR_LOAD_ANIM_MOVE_LEFT`
|
||||
* @param time time of the animation
|
||||
* @param delay delay before the transition
|
||||
* @param auto_del true: automatically delete the old screen
|
||||
*/
|
||||
void lv_scr_load_anim(lv_obj_t * scr, lv_scr_load_anim_t anim_type, uint32_t time, uint32_t delay, bool auto_del);
|
||||
|
||||
#endif
|
||||
/**
|
||||
* Get elapsed time since last user activity on a display (e.g. click)
|
||||
* @param disp pointer to an display (NULL to get the overall smallest inactivity)
|
||||
@@ -85,6 +133,14 @@ uint32_t lv_disp_get_inactive_time(const lv_disp_t * disp);
|
||||
*/
|
||||
void lv_disp_trig_activity(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Get a pointer to the screen refresher task to
|
||||
* modify its parameters with `lv_task_...` functions.
|
||||
* @param disp pointer to a display
|
||||
* @return pointer to the display refresher task. (NULL on error)
|
||||
*/
|
||||
lv_task_t * _lv_disp_get_refr_task(lv_disp_t * disp);
|
||||
|
||||
/*------------------------------------------------
|
||||
* To improve backward compatibility
|
||||
* Recommended only if you have one display
|
||||
@@ -122,6 +178,7 @@ static inline void lv_scr_load(lv_obj_t * scr)
|
||||
lv_disp_load_scr(scr);
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
@@ -152,7 +209,12 @@ static inline void lv_scr_load(lv_obj_t * scr)
|
||||
* 1 dip is 2 px on a 320 DPI screen
|
||||
* https://stackoverflow.com/questions/2025282/what-is-the-difference-between-px-dip-dp-and-sp
|
||||
*/
|
||||
#define LV_DPX(n) LV_MATH_MAX(((LV_DPI * (n) + 80) / 160), 1) /*+80 for rounding*/
|
||||
#define LV_DPX(n) (n == 0 ? 0 :LV_MATH_MAX((( lv_disp_get_dpi(NULL) * (n) + 80) / 160), 1)) /*+80 for rounding*/
|
||||
|
||||
static inline lv_coord_t lv_dpx(lv_coord_t n)
|
||||
{
|
||||
return LV_DPX(n);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "lv_group.h"
|
||||
#if LV_USE_GROUP != 0
|
||||
#include <stddef.h>
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "../lv_misc/lv_debug.h"
|
||||
#include "../lv_themes/lv_theme.h"
|
||||
#include "../lv_misc/lv_gc.h"
|
||||
|
||||
@@ -48,9 +48,9 @@ static void obj_to_foreground(lv_obj_t * obj);
|
||||
/**
|
||||
* Init. the group module
|
||||
*/
|
||||
void lv_group_init(void)
|
||||
void _lv_group_init(void)
|
||||
{
|
||||
lv_ll_init(&LV_GC_ROOT(_lv_group_ll), sizeof(lv_group_t));
|
||||
_lv_ll_init(&LV_GC_ROOT(_lv_group_ll), sizeof(lv_group_t));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,10 +59,10 @@ void lv_group_init(void)
|
||||
*/
|
||||
lv_group_t * lv_group_create(void)
|
||||
{
|
||||
lv_group_t * group = lv_ll_ins_head(&LV_GC_ROOT(_lv_group_ll));
|
||||
lv_group_t * group = _lv_ll_ins_head(&LV_GC_ROOT(_lv_group_ll));
|
||||
LV_ASSERT_MEM(group);
|
||||
if(group == NULL) return NULL;
|
||||
lv_ll_init(&group->obj_ll, sizeof(lv_obj_t *));
|
||||
_lv_ll_init(&group->obj_ll, sizeof(lv_obj_t *));
|
||||
|
||||
group->obj_focus = NULL;
|
||||
group->frozen = 0;
|
||||
@@ -73,7 +73,7 @@ lv_group_t * lv_group_create(void)
|
||||
group->wrap = 1;
|
||||
|
||||
#if LV_USE_USER_DATA
|
||||
lv_memset_00(&group->user_data, sizeof(lv_group_user_data_t));
|
||||
_lv_memset_00(&group->user_data, sizeof(lv_group_user_data_t));
|
||||
#endif
|
||||
|
||||
return group;
|
||||
@@ -93,12 +93,12 @@ void lv_group_del(lv_group_t * group)
|
||||
|
||||
/*Remove the objects from the group*/
|
||||
lv_obj_t ** obj;
|
||||
LV_LL_READ(group->obj_ll, obj) {
|
||||
_LV_LL_READ(group->obj_ll, obj) {
|
||||
(*obj)->group_p = NULL;
|
||||
}
|
||||
|
||||
lv_ll_clear(&(group->obj_ll));
|
||||
lv_ll_remove(&LV_GC_ROOT(_lv_group_ll), group);
|
||||
_lv_ll_clear(&(group->obj_ll));
|
||||
_lv_ll_remove(&LV_GC_ROOT(_lv_group_ll), group);
|
||||
lv_mem_free(group);
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj)
|
||||
if(group == NULL) return;
|
||||
/*Do not add the object twice*/
|
||||
lv_obj_t ** obj_i;
|
||||
LV_LL_READ(group->obj_ll, obj_i) {
|
||||
_LV_LL_READ(group->obj_ll, obj_i) {
|
||||
if((*obj_i) == obj) {
|
||||
LV_LOG_INFO("lv_group_add_obj: the object is already added to this group");
|
||||
return;
|
||||
@@ -129,14 +129,14 @@ void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj)
|
||||
}
|
||||
|
||||
obj->group_p = group;
|
||||
lv_obj_t ** next = lv_ll_ins_tail(&group->obj_ll);
|
||||
lv_obj_t ** next = _lv_ll_ins_tail(&group->obj_ll);
|
||||
LV_ASSERT_MEM(next);
|
||||
if(next == NULL) return;
|
||||
*next = obj;
|
||||
|
||||
/* If the head and the tail is equal then there is only one object in the linked list.
|
||||
* In this case automatically activate it*/
|
||||
if(lv_ll_get_head(&group->obj_ll) == next) {
|
||||
if(_lv_ll_get_head(&group->obj_ll) == next) {
|
||||
lv_group_refocus(group);
|
||||
}
|
||||
}
|
||||
@@ -156,7 +156,7 @@ void lv_group_remove_obj(lv_obj_t * obj)
|
||||
if(g->frozen) g->frozen = 0;
|
||||
|
||||
/*If this is the only object in the group then focus to nothing.*/
|
||||
if(lv_ll_get_head(&g->obj_ll) == g->obj_focus && lv_ll_get_tail(&g->obj_ll) == g->obj_focus) {
|
||||
if(_lv_ll_get_head(&g->obj_ll) == g->obj_focus && _lv_ll_get_tail(&g->obj_ll) == g->obj_focus) {
|
||||
(*g->obj_focus)->signal_cb(*g->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
|
||||
}
|
||||
/*If there more objects in the group then focus to the next/prev object*/
|
||||
@@ -174,9 +174,9 @@ void lv_group_remove_obj(lv_obj_t * obj)
|
||||
|
||||
/*Search the object and remove it from its group */
|
||||
lv_obj_t ** i;
|
||||
LV_LL_READ(g->obj_ll, i) {
|
||||
_LV_LL_READ(g->obj_ll, i) {
|
||||
if(*i == obj) {
|
||||
lv_ll_remove(&g->obj_ll, i);
|
||||
_lv_ll_remove(&g->obj_ll, i);
|
||||
lv_mem_free(i);
|
||||
obj->group_p = NULL;
|
||||
break;
|
||||
@@ -199,11 +199,11 @@ void lv_group_remove_all_objs(lv_group_t * group)
|
||||
|
||||
/*Remove the objects from the group*/
|
||||
lv_obj_t ** obj;
|
||||
LV_LL_READ(group->obj_ll, obj) {
|
||||
_LV_LL_READ(group->obj_ll, obj) {
|
||||
(*obj)->group_p = NULL;
|
||||
}
|
||||
|
||||
lv_ll_clear(&(group->obj_ll));
|
||||
_lv_ll_clear(&(group->obj_ll));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -224,7 +224,7 @@ void lv_group_focus_obj(lv_obj_t * obj)
|
||||
lv_group_set_editing(g, false);
|
||||
|
||||
lv_obj_t ** i;
|
||||
LV_LL_READ(g->obj_ll, i) {
|
||||
_LV_LL_READ(g->obj_ll, i) {
|
||||
if(*i == obj) {
|
||||
if(g->obj_focus != NULL) {
|
||||
(*g->obj_focus)->signal_cb(*g->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
|
||||
@@ -242,7 +242,7 @@ void lv_group_focus_obj(lv_obj_t * obj)
|
||||
if(res != LV_RES_OK) return;
|
||||
lv_obj_invalidate(*g->obj_focus);
|
||||
|
||||
/*If the object or its parent has `top == true` bring it to the foregorund*/
|
||||
/*If the object or its parent has `top == true` bring it to the foreground*/
|
||||
obj_to_foreground(*g->obj_focus);
|
||||
}
|
||||
break;
|
||||
@@ -256,7 +256,7 @@ void lv_group_focus_obj(lv_obj_t * obj)
|
||||
*/
|
||||
void lv_group_focus_next(lv_group_t * group)
|
||||
{
|
||||
focus_next_core(group, lv_ll_get_head, lv_ll_get_next);
|
||||
focus_next_core(group, _lv_ll_get_head, _lv_ll_get_next);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -265,7 +265,7 @@ void lv_group_focus_next(lv_group_t * group)
|
||||
*/
|
||||
void lv_group_focus_prev(lv_group_t * group)
|
||||
{
|
||||
focus_next_core(group, lv_ll_get_tail, lv_ll_get_prev);
|
||||
focus_next_core(group, _lv_ll_get_tail, _lv_ll_get_prev);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -508,7 +508,7 @@ static void focus_next_core(lv_group_t * group, void * (*begin)(const lv_ll_t *)
|
||||
lv_res_t res = lv_event_send(*group->obj_focus, LV_EVENT_FOCUSED, NULL);
|
||||
if(res != LV_RES_OK) return;
|
||||
|
||||
/*If the object or its parent has `top == true` bring it to the foregorund*/
|
||||
/*If the object or its parent has `top == true` bring it to the foreground*/
|
||||
obj_to_foreground(*group->obj_focus);
|
||||
|
||||
lv_obj_invalidate(*group->obj_focus);
|
||||
|
||||
@@ -81,7 +81,7 @@ typedef uint8_t lv_group_refocus_policy_t;
|
||||
* Init. the group module
|
||||
* @remarks Internal function, do not call directly.
|
||||
*/
|
||||
void lv_group_init(void);
|
||||
void _lv_group_init(void);
|
||||
|
||||
/**
|
||||
* Create a new object group
|
||||
@@ -155,7 +155,7 @@ lv_res_t lv_group_send_data(lv_group_t * group, uint32_t c);
|
||||
void lv_group_set_focus_cb(lv_group_t * group, lv_group_focus_cb_t focus_cb);
|
||||
|
||||
/**
|
||||
* Set whether the next or previous item in a group is focused if the currently focussed obj is
|
||||
* Set whether the next or previous item in a group is focused if the currently focused obj is
|
||||
* deleted.
|
||||
* @param group pointer to a group
|
||||
* @param new refocus policy enum
|
||||
|
||||
@@ -63,7 +63,7 @@ static lv_obj_t * indev_obj_act = NULL;
|
||||
/**
|
||||
* Initialize the display input device subsystem
|
||||
*/
|
||||
void lv_indev_init(void)
|
||||
void _lv_indev_init(void)
|
||||
{
|
||||
lv_indev_reset(NULL, NULL); /*Reset all input devices*/
|
||||
}
|
||||
@@ -72,7 +72,7 @@ void lv_indev_init(void)
|
||||
* Called periodically to read the input devices
|
||||
* @param param pointer to and input device to read
|
||||
*/
|
||||
void lv_indev_read_task(lv_task_t * task)
|
||||
void _lv_indev_read_task(lv_task_t * task)
|
||||
{
|
||||
LV_LOG_TRACE("indev read task started");
|
||||
|
||||
@@ -90,7 +90,7 @@ void lv_indev_read_task(lv_task_t * task)
|
||||
bool more_to_read;
|
||||
do {
|
||||
/*Read the data*/
|
||||
more_to_read = lv_indev_read(indev_act, &data);
|
||||
more_to_read = _lv_indev_read(indev_act, &data);
|
||||
|
||||
/*The active object might deleted even in the read function*/
|
||||
indev_proc_reset_query_handler(indev_act);
|
||||
@@ -213,6 +213,7 @@ void lv_indev_set_cursor(lv_indev_t * indev, lv_obj_t * cur_obj)
|
||||
indev->cursor = cur_obj;
|
||||
lv_obj_set_parent(indev->cursor, lv_disp_get_layer_sys(indev->driver.disp));
|
||||
lv_obj_set_pos(indev->cursor, indev->proc.types.pointer.act_point.x, indev->proc.types.pointer.act_point.y);
|
||||
lv_obj_set_click(indev->cursor, false);
|
||||
}
|
||||
|
||||
#if LV_USE_GROUP
|
||||
@@ -364,6 +365,15 @@ void lv_indev_wait_release(lv_indev_t * indev)
|
||||
indev->proc.wait_until_release = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a pointer to the currently active object in the currently processed input device.
|
||||
* @return pointer to currently active object or NULL if no active object
|
||||
*/
|
||||
lv_obj_t * lv_indev_get_obj_act(void)
|
||||
{
|
||||
return indev_obj_act;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a pointer to the indev read task to
|
||||
* modify its parameters with `lv_task_...` functions.
|
||||
@@ -380,15 +390,6 @@ lv_task_t * lv_indev_get_read_task(lv_disp_t * indev)
|
||||
return indev->refr_task;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a pointer to the currently active object in the currently processed input device.
|
||||
* @return pointer to currently active object or NULL if no active object
|
||||
*/
|
||||
lv_obj_t * lv_indev_get_obj_act(void)
|
||||
{
|
||||
return indev_obj_act;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
@@ -607,8 +608,163 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
|
||||
indev_obj_act = lv_group_get_focused(g);
|
||||
if(indev_obj_act == NULL) return;
|
||||
|
||||
/*Process the steps first. They are valid only with released button*/
|
||||
if(data->state == LV_INDEV_STATE_REL) {
|
||||
/*Process the steps they are valid only with released button*/
|
||||
if(data->state != LV_INDEV_STATE_REL) {
|
||||
data->enc_diff = 0;
|
||||
}
|
||||
|
||||
/*Refresh the focused object. It might change due to lv_group_focus_prev/next*/
|
||||
indev_obj_act = lv_group_get_focused(g);
|
||||
if(indev_obj_act == NULL) return;
|
||||
|
||||
/*Button press happened*/
|
||||
if(data->state == LV_INDEV_STATE_PR && last_state == LV_INDEV_STATE_REL) {
|
||||
|
||||
i->proc.pr_timestamp = lv_tick_get();
|
||||
|
||||
if(data->key == LV_KEY_ENTER) {
|
||||
bool editable = false;
|
||||
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_GET_EDITABLE, &editable);
|
||||
|
||||
if(lv_group_get_editing(g) == true || editable == false) {
|
||||
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_PRESSED, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
|
||||
lv_event_send(indev_obj_act, LV_EVENT_PRESSED, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
}
|
||||
}
|
||||
else if(data->key == LV_KEY_LEFT) {
|
||||
/*emulate encoder left*/
|
||||
data->enc_diff--;
|
||||
}
|
||||
else if(data->key == LV_KEY_RIGHT) {
|
||||
/*emulate encoder right*/
|
||||
data->enc_diff++;
|
||||
}
|
||||
else if(data->key == LV_KEY_ESC) {
|
||||
/*Send the ESC as a normal KEY*/
|
||||
lv_group_send_data(g, LV_KEY_ESC);
|
||||
|
||||
lv_event_send(indev_obj_act, LV_EVENT_CANCEL, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
}
|
||||
/*Just send other keys to the object (e.g. 'A' or `LV_GROUP_KEY_RIGHT`)*/
|
||||
else {
|
||||
lv_group_send_data(g, data->key);
|
||||
}
|
||||
}
|
||||
/*Pressing*/
|
||||
else if(data->state == LV_INDEV_STATE_PR && last_state == LV_INDEV_STATE_PR) {
|
||||
/* Long press*/
|
||||
if(i->proc.long_pr_sent == 0 && lv_tick_elaps(i->proc.pr_timestamp) > i->driver.long_press_time) {
|
||||
|
||||
i->proc.long_pr_sent = 1;
|
||||
i->proc.longpr_rep_timestamp = lv_tick_get();
|
||||
|
||||
if(data->key == LV_KEY_ENTER) {
|
||||
bool editable = false;
|
||||
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_GET_EDITABLE, &editable);
|
||||
|
||||
/*On enter long press toggle edit mode.*/
|
||||
if(editable) {
|
||||
/*Don't leave edit mode if there is only one object (nowhere to navigate)*/
|
||||
if(_lv_ll_is_empty(&g->obj_ll) == false) {
|
||||
lv_group_set_editing(g, lv_group_get_editing(g) ? false : true); /*Toggle edit mode on long press*/
|
||||
}
|
||||
}
|
||||
/*If not editable then just send a long press signal*/
|
||||
else {
|
||||
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_LONG_PRESS, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
lv_event_send(indev_obj_act, LV_EVENT_LONG_PRESSED, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
}
|
||||
}
|
||||
|
||||
i->proc.long_pr_sent = 1;
|
||||
}
|
||||
/*Long press repeated time has elapsed?*/
|
||||
else if(i->proc.long_pr_sent != 0 && lv_tick_elaps(i->proc.longpr_rep_timestamp) > i->driver.long_press_rep_time) {
|
||||
|
||||
i->proc.longpr_rep_timestamp = lv_tick_get();
|
||||
|
||||
if(data->key == LV_KEY_ENTER) {
|
||||
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_LONG_PRESS_REP, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
lv_event_send(indev_obj_act, LV_EVENT_LONG_PRESSED_REPEAT, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
}
|
||||
else if(data->key == LV_KEY_LEFT) {
|
||||
/*emulate encoder left*/
|
||||
data->enc_diff--;
|
||||
}
|
||||
else if(data->key == LV_KEY_RIGHT) {
|
||||
/*emulate encoder right*/
|
||||
data->enc_diff++;
|
||||
}
|
||||
else {
|
||||
lv_group_send_data(g, data->key);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
/*Release happened*/
|
||||
else if(data->state == LV_INDEV_STATE_REL && last_state == LV_INDEV_STATE_PR) {
|
||||
|
||||
if(data->key == LV_KEY_ENTER) {
|
||||
bool editable = false;
|
||||
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_GET_EDITABLE, &editable);
|
||||
|
||||
/*The button was released on a non-editable object. Just send enter*/
|
||||
if(editable == false) {
|
||||
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_RELEASED, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
|
||||
if(i->proc.long_pr_sent == 0) lv_event_send(indev_obj_act, LV_EVENT_SHORT_CLICKED, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
|
||||
lv_event_send(indev_obj_act, LV_EVENT_CLICKED, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
|
||||
lv_event_send(indev_obj_act, LV_EVENT_RELEASED, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
}
|
||||
/*An object is being edited and the button is released. */
|
||||
else if(g->editing) {
|
||||
/*Ignore long pressed enter release because it comes from mode switch*/
|
||||
if(!i->proc.long_pr_sent || _lv_ll_is_empty(&g->obj_ll)) {
|
||||
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_RELEASED, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
|
||||
lv_event_send(indev_obj_act, LV_EVENT_SHORT_CLICKED, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
|
||||
lv_event_send(indev_obj_act, LV_EVENT_CLICKED, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
|
||||
lv_event_send(indev_obj_act, LV_EVENT_RELEASED, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
|
||||
lv_group_send_data(g, LV_KEY_ENTER);
|
||||
}
|
||||
}
|
||||
/*If the focused object is editable and now in navigate mode then on enter switch edit
|
||||
mode*/
|
||||
else if(editable && !g->editing && !i->proc.long_pr_sent) {
|
||||
lv_group_set_editing(g, true); /*Set edit mode*/
|
||||
}
|
||||
}
|
||||
|
||||
i->proc.pr_timestamp = 0;
|
||||
i->proc.long_pr_sent = 0;
|
||||
}
|
||||
indev_obj_act = NULL;
|
||||
|
||||
/*if encoder steps or simulated steps via left/right keys*/
|
||||
if(data->enc_diff != 0) {
|
||||
/*In edit mode send LEFT/RIGHT keys*/
|
||||
if(lv_group_get_editing(g)) {
|
||||
int32_t s;
|
||||
@@ -631,96 +787,6 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
|
||||
}
|
||||
}
|
||||
|
||||
/*Refresh the focused object. It might change due to lv_group_focus_prev/next*/
|
||||
indev_obj_act = lv_group_get_focused(g);
|
||||
if(indev_obj_act == NULL) return;
|
||||
|
||||
/*Button press happened*/
|
||||
if(data->state == LV_INDEV_STATE_PR && last_state == LV_INDEV_STATE_REL) {
|
||||
bool editable = false;
|
||||
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_GET_EDITABLE, &editable);
|
||||
|
||||
i->proc.pr_timestamp = lv_tick_get();
|
||||
if(lv_group_get_editing(g) == true || editable == false) {
|
||||
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_PRESSED, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
|
||||
lv_event_send(indev_obj_act, LV_EVENT_PRESSED, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
}
|
||||
}
|
||||
/*Pressing*/
|
||||
else if(data->state == LV_INDEV_STATE_PR && last_state == LV_INDEV_STATE_PR) {
|
||||
if(i->proc.long_pr_sent == 0 && lv_tick_elaps(i->proc.pr_timestamp) > i->driver.long_press_time) {
|
||||
bool editable = false;
|
||||
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_GET_EDITABLE, &editable);
|
||||
|
||||
/*On enter long press toggle edit mode.*/
|
||||
if(editable) {
|
||||
/*Don't leave edit mode if there is only one object (nowhere to navigate)*/
|
||||
if(lv_ll_is_empty(&g->obj_ll) == false) {
|
||||
lv_group_set_editing(g, lv_group_get_editing(g) ? false : true); /*Toggle edit mode on long press*/
|
||||
}
|
||||
}
|
||||
/*If not editable then just send a long press signal*/
|
||||
else {
|
||||
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_LONG_PRESS, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
lv_event_send(indev_obj_act, LV_EVENT_LONG_PRESSED, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
}
|
||||
i->proc.long_pr_sent = 1;
|
||||
}
|
||||
}
|
||||
/*Release happened*/
|
||||
else if(data->state == LV_INDEV_STATE_REL && last_state == LV_INDEV_STATE_PR) {
|
||||
|
||||
bool editable = false;
|
||||
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_GET_EDITABLE, &editable);
|
||||
|
||||
/*The button was released on a non-editable object. Just send enter*/
|
||||
if(editable == false) {
|
||||
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_RELEASED, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
|
||||
if(i->proc.long_pr_sent == 0) lv_event_send(indev_obj_act, LV_EVENT_SHORT_CLICKED, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
|
||||
lv_event_send(indev_obj_act, LV_EVENT_CLICKED, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
|
||||
lv_event_send(indev_obj_act, LV_EVENT_RELEASED, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
}
|
||||
/*An object is being edited and the button is released. */
|
||||
else if(g->editing) {
|
||||
/*Ignore long pressed enter release because it comes from mode switch*/
|
||||
if(!i->proc.long_pr_sent || lv_ll_is_empty(&g->obj_ll)) {
|
||||
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_RELEASED, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
|
||||
lv_event_send(indev_obj_act, LV_EVENT_SHORT_CLICKED, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
|
||||
lv_event_send(indev_obj_act, LV_EVENT_CLICKED, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
|
||||
lv_event_send(indev_obj_act, LV_EVENT_RELEASED, NULL);
|
||||
if(indev_reset_check(&i->proc)) return;
|
||||
|
||||
lv_group_send_data(g, LV_KEY_ENTER);
|
||||
}
|
||||
}
|
||||
/*If the focused object is editable and now in navigate mode then on enter switch edit
|
||||
mode*/
|
||||
else if(editable && !g->editing && !i->proc.long_pr_sent) {
|
||||
lv_group_set_editing(g, true); /*Set edit mode*/
|
||||
}
|
||||
|
||||
i->proc.pr_timestamp = 0;
|
||||
i->proc.long_pr_sent = 0;
|
||||
}
|
||||
indev_obj_act = NULL;
|
||||
#else
|
||||
(void)data; /*Unused*/
|
||||
(void)i; /*Unused*/
|
||||
@@ -735,6 +801,12 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
|
||||
*/
|
||||
static void indev_button_proc(lv_indev_t * i, lv_indev_data_t * data)
|
||||
{
|
||||
/* Die gracefully if i->btn_points is NULL */
|
||||
if(i->btn_points == NULL) {
|
||||
LV_LOG_WARN("indev_button_proc: btn_points was NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
i->proc.types.pointer.act_point.x = i->btn_points[data->btn_id].x;
|
||||
i->proc.types.pointer.act_point.y = i->btn_points[data->btn_id].y;
|
||||
|
||||
@@ -785,7 +857,7 @@ static void indev_proc_press(lv_indev_proc_t * proc)
|
||||
&proc->types.pointer.act_point);
|
||||
new_obj_searched = true;
|
||||
}
|
||||
/*If a dragable or a protected object was the last then keep it*/
|
||||
/*If a draggable or a protected object was the last then keep it*/
|
||||
else {
|
||||
}
|
||||
|
||||
@@ -1043,7 +1115,7 @@ static void indev_proc_reset_query_handler(lv_indev_t * indev)
|
||||
/**
|
||||
* Search the most top, clickable object by a point
|
||||
* @param obj pointer to a start object, typically the screen
|
||||
* @param point pointer to a point for searhing the most top child
|
||||
* @param point pointer to a point for searching the most top child
|
||||
* @return pointer to the found object or NULL if there was no suitable object
|
||||
*/
|
||||
lv_obj_t * lv_indev_search_obj(lv_obj_t * obj, lv_point_t * point)
|
||||
@@ -1054,7 +1126,7 @@ lv_obj_t * lv_indev_search_obj(lv_obj_t * obj, lv_point_t * point)
|
||||
if(lv_obj_hittest(obj, point)) {
|
||||
lv_obj_t * i;
|
||||
|
||||
LV_LL_READ(obj->child_ll, i) {
|
||||
_LV_LL_READ(obj->child_ll, i) {
|
||||
found_p = lv_indev_search_obj(i, point);
|
||||
|
||||
/*If a child was found then break*/
|
||||
@@ -1080,14 +1152,15 @@ lv_obj_t * lv_indev_search_obj(lv_obj_t * obj, lv_point_t * point)
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle focus/defocus on click for POINTER inpt devices
|
||||
* Handle focus/defocus on click for POINTER input devices
|
||||
* @param proc pointer to the state of the indev
|
||||
*/
|
||||
static void indev_click_focus(lv_indev_proc_t * proc)
|
||||
{
|
||||
/*Handle click focus*/
|
||||
lv_obj_t * obj_to_focus = lv_obj_get_focused_obj(indev_obj_act);
|
||||
if(lv_obj_is_protected(indev_obj_act, LV_PROTECT_CLICK_FOCUS) == false &&
|
||||
proc->types.pointer.last_pressed != indev_obj_act) {
|
||||
proc->types.pointer.last_pressed != obj_to_focus) {
|
||||
#if LV_USE_GROUP
|
||||
lv_group_t * g_act = lv_obj_get_group(indev_obj_act);
|
||||
lv_group_t * g_prev = proc->types.pointer.last_pressed ? lv_obj_get_group(proc->types.pointer.last_pressed) : NULL;
|
||||
@@ -1116,11 +1189,6 @@ static void indev_click_focus(lv_indev_proc_t * proc)
|
||||
}
|
||||
/*The object are not in the same group (in different group or one in not a group)*/
|
||||
else {
|
||||
/*Focus to the act. its group*/
|
||||
if(g_act) {
|
||||
lv_group_focus_obj(indev_obj_act);
|
||||
if(indev_reset_check(proc)) return;
|
||||
}
|
||||
/*If the prev. obj. is not in a group then defocus it.*/
|
||||
if(g_prev == NULL && proc->types.pointer.last_pressed) {
|
||||
lv_signal_send(proc->types.pointer.last_pressed, LV_SIGNAL_DEFOCUS, NULL);
|
||||
@@ -1146,7 +1214,14 @@ static void indev_click_focus(lv_indev_proc_t * proc)
|
||||
if(indev_reset_check(proc)) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*Focus to the act. in its group*/
|
||||
if(g_act) {
|
||||
lv_group_focus_obj(indev_obj_act);
|
||||
if(indev_reset_check(proc)) return;
|
||||
}
|
||||
else {
|
||||
lv_signal_send(indev_obj_act, LV_SIGNAL_FOCUS, NULL);
|
||||
if(indev_reset_check(proc)) return;
|
||||
lv_event_send(indev_obj_act, LV_EVENT_FOCUSED, NULL);
|
||||
@@ -1166,7 +1241,7 @@ static void indev_click_focus(lv_indev_proc_t * proc)
|
||||
lv_event_send(indev_obj_act, LV_EVENT_FOCUSED, NULL);
|
||||
if(indev_reset_check(proc)) return;
|
||||
#endif
|
||||
proc->types.pointer.last_pressed = indev_obj_act;
|
||||
proc->types.pointer.last_pressed = obj_to_focus;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1299,7 +1374,7 @@ static void indev_drag(lv_indev_proc_t * proc)
|
||||
lv_coord_t act_par_h = lv_obj_get_height(lv_obj_get_parent(drag_obj));
|
||||
if(act_par_w == prev_par_w && act_par_h == prev_par_h) {
|
||||
uint16_t new_inv_buf_size = lv_disp_get_inv_buf_size(indev_act->driver.disp);
|
||||
lv_disp_pop_from_inv_buf(indev_act->driver.disp, new_inv_buf_size - inv_buf_size);
|
||||
_lv_disp_pop_from_inv_buf(indev_act->driver.disp, new_inv_buf_size - inv_buf_size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1393,7 +1468,7 @@ static void indev_drag_throw(lv_indev_proc_t * proc)
|
||||
|
||||
/**
|
||||
* Get the really dragged object by taking `drag_parent` into account.
|
||||
* @param obj the start obejct
|
||||
* @param obj the start object
|
||||
* @return the object to really drag
|
||||
*/
|
||||
static lv_obj_t * get_dragged_obj(lv_obj_t * obj)
|
||||
@@ -1415,18 +1490,18 @@ static lv_obj_t * get_dragged_obj(lv_obj_t * obj)
|
||||
static void indev_gesture(lv_indev_proc_t * proc)
|
||||
{
|
||||
|
||||
if(proc->types.pointer.drag_in_prog) return;
|
||||
if(proc->types.pointer.gesture_sent) return;
|
||||
|
||||
lv_obj_t * gesture_obj = proc->types.pointer.act_obj;
|
||||
|
||||
/*If gesture parent is active check recursively the drag_parent attribute*/
|
||||
/*If gesture parent is active check recursively the gesture attribute*/
|
||||
while(gesture_obj && lv_obj_get_gesture_parent(gesture_obj)) {
|
||||
gesture_obj = lv_obj_get_parent(gesture_obj);
|
||||
}
|
||||
|
||||
if(gesture_obj == NULL) return;
|
||||
|
||||
|
||||
if((LV_MATH_ABS(proc->types.pointer.vect.x) < indev_act->driver.gesture_min_velocity) &&
|
||||
(LV_MATH_ABS(proc->types.pointer.vect.y) < indev_act->driver.gesture_min_velocity)) {
|
||||
proc->types.pointer.gesture_sum.x = 0;
|
||||
|
||||
@@ -32,13 +32,13 @@ extern "C" {
|
||||
/**
|
||||
* Initialize the display input device subsystem
|
||||
*/
|
||||
void lv_indev_init(void);
|
||||
void _lv_indev_init(void);
|
||||
|
||||
/**
|
||||
* Called periodically to read the input devices
|
||||
* @param task pointer to the task itself
|
||||
*/
|
||||
void lv_indev_read_task(lv_task_t * task);
|
||||
void _lv_indev_read_task(lv_task_t * task);
|
||||
|
||||
/**
|
||||
* Get the currently processed input device. Can be used in action functions too.
|
||||
@@ -149,13 +149,6 @@ lv_res_t lv_indev_finish_drag(lv_indev_t * indev);
|
||||
*/
|
||||
void lv_indev_wait_release(lv_indev_t * indev);
|
||||
|
||||
/**
|
||||
* Get a pointer to the indev read task to
|
||||
* modify its parameters with `lv_task_...` functions.
|
||||
* @param indev pointer to an inout device
|
||||
* @return pointer to the indev read refresher task. (NULL on error)
|
||||
*/
|
||||
lv_task_t * lv_indev_get_read_task(lv_disp_t * indev);
|
||||
|
||||
/**
|
||||
* Gets a pointer to the currently active object in indev proc functions.
|
||||
@@ -167,11 +160,19 @@ lv_obj_t * lv_indev_get_obj_act(void);
|
||||
/**
|
||||
* Search the most top, clickable object by a point
|
||||
* @param obj pointer to a start object, typically the screen
|
||||
* @param point pointer to a point for searhing the most top child
|
||||
* @param point pointer to a point for searching the most top child
|
||||
* @return pointer to the found object or NULL if there was no suitable object
|
||||
*/
|
||||
lv_obj_t * lv_indev_search_obj(lv_obj_t * obj, lv_point_t * point);
|
||||
|
||||
/**
|
||||
* Get a pointer to the indev read task to
|
||||
* modify its parameters with `lv_task_...` functions.
|
||||
* @param indev pointer to an inout device
|
||||
* @return pointer to the indev read refresher task. (NULL on error)
|
||||
*/
|
||||
lv_task_t * lv_indev_get_read_task(lv_disp_t * indev);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
1395
src/lv_core/lv_obj.c
1395
src/lv_core/lv_obj.c
File diff suppressed because it is too large
Load Diff
@@ -20,10 +20,8 @@ extern "C" {
|
||||
#include "lv_style.h"
|
||||
#include "../lv_misc/lv_types.h"
|
||||
#include "../lv_misc/lv_area.h"
|
||||
#include "../lv_misc/lv_mem.h"
|
||||
#include "../lv_misc/lv_ll.h"
|
||||
#include "../lv_misc/lv_color.h"
|
||||
#include "../lv_misc/lv_bidi.h"
|
||||
#include "../lv_misc/lv_debug.h"
|
||||
#include "../lv_hal/lv_hal.h"
|
||||
#include "../lv_draw/lv_draw_rect.h"
|
||||
#include "../lv_draw/lv_draw_label.h"
|
||||
@@ -36,11 +34,11 @@ extern "C" {
|
||||
|
||||
/*Error check of lv_conf.h*/
|
||||
#if LV_HOR_RES_MAX == 0 || LV_VER_RES_MAX == 0
|
||||
#error "LittlevGL: LV_HOR_RES_MAX and LV_VER_RES_MAX must be greater than 0"
|
||||
#error "LVGL: LV_HOR_RES_MAX and LV_VER_RES_MAX must be greater than 0"
|
||||
#endif
|
||||
|
||||
#if LV_ANTIALIAS > 1
|
||||
#error "LittlevGL: LV_ANTIALIAS can be only 0 or 1"
|
||||
#error "LVGL: LV_ANTIALIAS can be only 0 or 1"
|
||||
#endif
|
||||
|
||||
#define LV_MAX_ANCESTOR_NUM 8
|
||||
@@ -49,6 +47,9 @@ extern "C" {
|
||||
#define LV_EXT_CLICK_AREA_TINY 1
|
||||
#define LV_EXT_CLICK_AREA_FULL 2
|
||||
|
||||
#define _LV_OBJ_PART_VIRTUAL_FIRST 0x01
|
||||
#define _LV_OBJ_PART_REAL_FIRST 0x40
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
@@ -93,7 +94,7 @@ enum {
|
||||
LV_EVENT_DRAG_BEGIN,
|
||||
LV_EVENT_DRAG_END,
|
||||
LV_EVENT_DRAG_THROW_BEGIN,
|
||||
LV_EVENT_GESTURE, /**< The object has been getture*/
|
||||
LV_EVENT_GESTURE, /**< The object has been gesture*/
|
||||
LV_EVENT_KEY,
|
||||
LV_EVENT_FOCUSED,
|
||||
LV_EVENT_DEFOCUSED,
|
||||
@@ -104,6 +105,7 @@ enum {
|
||||
LV_EVENT_APPLY, /**< "Ok", "Apply" or similar specific button has clicked*/
|
||||
LV_EVENT_CANCEL, /**< "Close", "Cancel" or similar specific button has clicked*/
|
||||
LV_EVENT_DELETE, /**< Object is being deleted */
|
||||
_LV_EVENT_LAST /** Number of events*/
|
||||
};
|
||||
typedef uint8_t lv_event_t; /**< Type of event being sent to the object. */
|
||||
|
||||
@@ -126,7 +128,7 @@ enum {
|
||||
LV_SIGNAL_STYLE_CHG, /**< Object's style has changed */
|
||||
LV_SIGNAL_BASE_DIR_CHG, /**<The base dir has changed*/
|
||||
LV_SIGNAL_REFR_EXT_DRAW_PAD, /**< Object's extra padding has changed */
|
||||
LV_SIGNAL_GET_TYPE, /**< LittlevGL needs to retrieve the object's type */
|
||||
LV_SIGNAL_GET_TYPE, /**< LVGL needs to retrieve the object's type */
|
||||
LV_SIGNAL_GET_STYLE, /**<Get the style of an object*/
|
||||
LV_SIGNAL_GET_STATE_DSC, /**<Get the state of the object*/
|
||||
|
||||
@@ -161,7 +163,7 @@ typedef struct {
|
||||
lv_coord_t yofs;
|
||||
lv_align_t align;
|
||||
uint8_t auto_realign : 1;
|
||||
uint8_t origo_align : 1; /**< 1: the origo (center of the object) was aligned with
|
||||
uint8_t mid_align : 1; /**< 1: the origo (center of the object) was aligned with
|
||||
`lv_obj_align_origo`*/
|
||||
} lv_realign_t;
|
||||
#endif
|
||||
@@ -212,7 +214,7 @@ typedef struct _lv_obj_t {
|
||||
lv_area_t ext_click_pad; /**< Extra click padding area. */
|
||||
#endif
|
||||
|
||||
lv_coord_t ext_draw_pad; /**< EXTtend the size in every direction for drawing. */
|
||||
lv_coord_t ext_draw_pad; /**< EXTend the size in every direction for drawing. */
|
||||
|
||||
/*Attributes and states*/
|
||||
uint8_t click : 1; /**< 1: Can be pressed by an input device*/
|
||||
@@ -223,7 +225,8 @@ typedef struct _lv_obj_t {
|
||||
uint8_t top : 1; /**< 1: If the object or its children is clicked it goes to the foreground*/
|
||||
uint8_t parent_event : 1; /**< 1: Send the object's events to the parent too. */
|
||||
uint8_t adv_hittest : 1; /**< 1: Use advanced hit-testing (slower) */
|
||||
uint8_t gesture_parent : 1; /**< 1: Parent will be gesture instead*/
|
||||
uint8_t gesture_parent : 1; /**< 1: Parent will be gesture instead*/
|
||||
uint8_t focus_parent : 1; /**< 1: Parent will be focused instead*/
|
||||
|
||||
lv_drag_dir_t drag_dir : 3; /**< Which directions the object can be dragged in */
|
||||
lv_bidi_dir_t base_dir : 2; /**< Base direction of texts related to this object */
|
||||
@@ -248,8 +251,8 @@ typedef struct _lv_obj_t {
|
||||
|
||||
enum {
|
||||
LV_OBJ_PART_MAIN,
|
||||
_LV_OBJ_PART_VIRTUAL_LAST = 0x01,
|
||||
_LV_OBJ_PART_REAL_LAST = 0x40,
|
||||
_LV_OBJ_PART_VIRTUAL_LAST = _LV_OBJ_PART_VIRTUAL_FIRST,
|
||||
_LV_OBJ_PART_REAL_LAST = _LV_OBJ_PART_REAL_FIRST,
|
||||
LV_OBJ_PART_ALL = 0xFF,
|
||||
};
|
||||
|
||||
@@ -351,6 +354,22 @@ void lv_obj_invalidate_area(const lv_obj_t * obj, const lv_area_t * area);
|
||||
*/
|
||||
void lv_obj_invalidate(const lv_obj_t * obj);
|
||||
|
||||
|
||||
/**
|
||||
* Tell whether an area of an object is visible (even partially) now or not
|
||||
* @param obj pointer to an object
|
||||
* @param area the are to check. The visible part of the area will be written back here.
|
||||
* @return true: visible; false: not visible (hidden, out of parent, on other screen, etc)
|
||||
*/
|
||||
bool lv_obj_area_is_visible(const lv_obj_t * obj, lv_area_t * area);
|
||||
|
||||
/**
|
||||
* Tell whether an object is visible (even partially) now or not
|
||||
* @param obj pointer to an object
|
||||
* @return true: visible; false: not visible (hidden, out of parent, on other screen, etc)
|
||||
*/
|
||||
bool lv_obj_is_visible(const lv_obj_t * obj);
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
@@ -442,7 +461,7 @@ void lv_obj_set_height_fit(lv_obj_t * obj, lv_coord_t h);
|
||||
|
||||
/**
|
||||
* Set the width of an object by taking the left and right margin into account.
|
||||
* The object width will be `obj_w = w - margon_left - margin_right`
|
||||
* The object width will be `obj_w = w - margin_left - margin_right`
|
||||
* @param obj pointer to an object
|
||||
* @param w new height including margins
|
||||
*/
|
||||
@@ -450,7 +469,7 @@ void lv_obj_set_width_margin(lv_obj_t * obj, lv_coord_t w);
|
||||
|
||||
/**
|
||||
* Set the height of an object by taking the top and bottom margin into account.
|
||||
* The object height will be `obj_h = h - margon_top - margin_bottom`
|
||||
* The object height will be `obj_h = h - margin_top - margin_bottom`
|
||||
* @param obj pointer to an object
|
||||
* @param h new height including margins
|
||||
*/
|
||||
@@ -466,6 +485,24 @@ void lv_obj_set_height_margin(lv_obj_t * obj, lv_coord_t h);
|
||||
*/
|
||||
void lv_obj_align(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_ofs, lv_coord_t y_ofs);
|
||||
|
||||
/**
|
||||
* Align an object to an other object horizontally.
|
||||
* @param obj pointer to an object to align
|
||||
* @param base pointer to an object (if NULL the parent is used). 'obj' will be aligned to it.
|
||||
* @param align type of alignment (see 'lv_align_t' enum)
|
||||
* @param x_ofs x coordinate offset after alignment
|
||||
*/
|
||||
void lv_obj_align_x(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_ofs);
|
||||
|
||||
/**
|
||||
* Align an object to an other object vertically.
|
||||
* @param obj pointer to an object to align
|
||||
* @param base pointer to an object (if NULL the parent is used). 'obj' will be aligned to it.
|
||||
* @param align type of alignment (see 'lv_align_t' enum)
|
||||
* @param y_ofs y coordinate offset after alignment
|
||||
*/
|
||||
void lv_obj_align_y(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t y_ofs);
|
||||
|
||||
/**
|
||||
* Align an object to an other object.
|
||||
* @param obj pointer to an object to align
|
||||
@@ -474,7 +511,26 @@ void lv_obj_align(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_co
|
||||
* @param x_ofs x coordinate offset after alignment
|
||||
* @param y_ofs y coordinate offset after alignment
|
||||
*/
|
||||
void lv_obj_align_origo(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_ofs, lv_coord_t y_ofs);
|
||||
void lv_obj_align_mid(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_ofs, lv_coord_t y_ofs);
|
||||
|
||||
|
||||
/**
|
||||
* Align an object's middle point to an other object horizontally.
|
||||
* @param obj pointer to an object to align
|
||||
* @param base pointer to an object (if NULL the parent is used). 'obj' will be aligned to it.
|
||||
* @param align type of alignment (see 'lv_align_t' enum)
|
||||
* @param x_ofs x coordinate offset after alignment
|
||||
*/
|
||||
void lv_obj_align_mid_x(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_ofs);
|
||||
|
||||
/**
|
||||
* Align an object's middle point to an other object vertically.
|
||||
* @param obj pointer to an object to align
|
||||
* @param base pointer to an object (if NULL the parent is used). 'obj' will be aligned to it.
|
||||
* @param align type of alignment (see 'lv_align_t' enum)
|
||||
* @param y_ofs y coordinate offset after alignment
|
||||
*/
|
||||
void lv_obj_align_mid_y(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t y_ofs);
|
||||
|
||||
/**
|
||||
* Realign the object based on the last `lv_obj_align` parameters.
|
||||
@@ -505,7 +561,7 @@ void lv_obj_set_ext_click_area(lv_obj_t * obj, lv_coord_t left, lv_coord_t right
|
||||
*--------------------*/
|
||||
|
||||
/**
|
||||
* Add a new stye to the style list of an object.
|
||||
* Add a new style to the style list of an object.
|
||||
* @param obj pointer to an object
|
||||
* @param part the part of the object which style property should be set.
|
||||
* E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_MAIN`, `LV_SLIDER_PART_KNOB`
|
||||
@@ -513,6 +569,15 @@ void lv_obj_set_ext_click_area(lv_obj_t * obj, lv_coord_t left, lv_coord_t right
|
||||
*/
|
||||
void lv_obj_add_style(lv_obj_t * obj, uint8_t part, lv_style_t * style);
|
||||
|
||||
/**
|
||||
* Remove a style from the style list of an object.
|
||||
* @param obj pointer to an object
|
||||
* @param part the part of the object which style property should be set.
|
||||
* E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_MAIN`, `LV_SLIDER_PART_KNOB`
|
||||
* @param style pointer to a style to remove
|
||||
*/
|
||||
void lv_obj_remove_style(lv_obj_t * obj, uint8_t part, lv_style_t * style);
|
||||
|
||||
/**
|
||||
* Reset a style to the default (empty) state.
|
||||
* Release all used memories and cancel pending related transitions.
|
||||
@@ -538,7 +603,7 @@ void lv_obj_reset_style_list(lv_obj_t * obj, uint8_t part);
|
||||
* @param obj pointer to an object
|
||||
* @param prop `LV_STYLE_PROP_ALL` or an `LV_STYLE_...` property. It is used to optimize what needs to be refreshed.
|
||||
*/
|
||||
void lv_obj_refresh_style(lv_obj_t * obj, lv_style_property_t prop);
|
||||
void lv_obj_refresh_style(lv_obj_t * obj, uint8_t part, lv_style_property_t prop);
|
||||
|
||||
/**
|
||||
* Notify all object if a style is modified
|
||||
@@ -612,9 +677,16 @@ void _lv_obj_set_style_local_ptr(lv_obj_t * obj, uint8_t type, lv_style_property
|
||||
* E.g. `LV_STYLE_TEXT_FONT | (LV_STATE_PRESSED << LV_STYLE_STATE_POS)`
|
||||
* @note shouldn't be used directly. Use the specific property remove functions instead.
|
||||
* For example: `lv_obj_style_remove_border_opa()`
|
||||
* @return true: the property was found and removed; false: teh property was not found
|
||||
* @return true: the property was found and removed; false: the property was not found
|
||||
*/
|
||||
bool _lv_obj_remove_style_local_prop(lv_obj_t * obj, uint8_t part, lv_style_property_t prop);
|
||||
bool lv_obj_remove_style_local_prop(lv_obj_t * obj, uint8_t part, lv_style_property_t prop);
|
||||
|
||||
/**
|
||||
* Enable/disable the use of style cahche for an object
|
||||
* @param obj pointer to an object
|
||||
* @param dis true: disable; false: enable (re-enable)
|
||||
*/
|
||||
void _lv_obj_disable_style_caching(lv_obj_t * obj, bool dis);
|
||||
|
||||
/*-----------------
|
||||
* Attribute set
|
||||
@@ -652,7 +724,7 @@ void lv_obj_set_top(lv_obj_t * obj, bool en);
|
||||
/**
|
||||
* Enable the dragging of an object
|
||||
* @param obj pointer to an object
|
||||
* @param en true: make the object dragable
|
||||
* @param en true: make the object draggable
|
||||
*/
|
||||
void lv_obj_set_drag(lv_obj_t * obj, bool en);
|
||||
|
||||
@@ -678,6 +750,14 @@ void lv_obj_set_drag_throw(lv_obj_t * obj, bool en);
|
||||
*/
|
||||
void lv_obj_set_drag_parent(lv_obj_t * obj, bool en);
|
||||
|
||||
/**
|
||||
* Enable to use parent for focus state.
|
||||
* When object is focused the parent will get the state instead (visual only)
|
||||
* @param obj pointer to an object
|
||||
* @param en true: enable the 'focus parent' for the object
|
||||
*/
|
||||
void lv_obj_set_focus_parent(lv_obj_t * obj, bool en);
|
||||
|
||||
/**
|
||||
* Enable to use parent for gesture related operations.
|
||||
* If trying to gesture the object the parent will be moved instead
|
||||
@@ -767,6 +847,20 @@ void lv_obj_set_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb);
|
||||
*/
|
||||
lv_res_t lv_event_send(lv_obj_t * obj, lv_event_t event, const void * data);
|
||||
|
||||
|
||||
/**
|
||||
* Send LV_EVENT_REFRESH event to an object
|
||||
* @param obj point to an obejct. (Can NOT be NULL)
|
||||
* @return LV_RES_OK: success, LV_RES_INV: to object become invalid (e.g. deleted) due to this event.
|
||||
*/
|
||||
lv_res_t lv_event_send_refresh(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Send LV_EVENT_REFRESH event to an object and all of its children
|
||||
* @param obj pointer to an object or NULL to refresh all objects of all displays
|
||||
*/
|
||||
void lv_event_send_refresh_recursive(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Call an event function with an object, event, and data.
|
||||
* @param event_xcb an event callback function. If `NULL` `LV_RES_OK` will return without any actions.
|
||||
@@ -841,7 +935,6 @@ lv_obj_t * lv_obj_get_screen(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the display of an object
|
||||
* @param scr pointer to an object
|
||||
* @return pointer the object's display
|
||||
*/
|
||||
lv_disp_t * lv_obj_get_disp(const lv_obj_t * obj);
|
||||
@@ -950,7 +1043,7 @@ lv_coord_t lv_obj_get_height_fit(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the height of an object by taking the top and bottom margin into account.
|
||||
* The returned height will be `obj_h + margon_top + margin_bottom`
|
||||
* The returned height will be `obj_h + margin_top + margin_bottom`
|
||||
* @param obj pointer to an object
|
||||
* @return the height including thee margins
|
||||
*/
|
||||
@@ -958,7 +1051,7 @@ lv_coord_t lv_obj_get_height_margin(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the width of an object by taking the left and right margin into account.
|
||||
* The returned width will be `obj_w + margon_left + margin_right`
|
||||
* The returned width will be `obj_w + margin_left + margin_right`
|
||||
* @param obj pointer to an object
|
||||
* @return the height including thee margins
|
||||
*/
|
||||
@@ -1037,7 +1130,7 @@ lv_coord_t lv_obj_get_ext_draw_pad(const lv_obj_t * obj);
|
||||
*---------------*/
|
||||
|
||||
/**
|
||||
* Get the style list of an obejct's part.
|
||||
* Get the style list of an object's part.
|
||||
* @param obj pointer to an object.
|
||||
* @param part part the part of the object which style list should be get.
|
||||
* E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_MAIN`, `LV_SLIDER_PART_KNOB`
|
||||
@@ -1156,7 +1249,7 @@ bool lv_obj_get_top(const lv_obj_t * obj);
|
||||
/**
|
||||
* Get the drag enable attribute of an object
|
||||
* @param obj pointer to an object
|
||||
* @return true: the object is dragable
|
||||
* @return true: the object is draggable
|
||||
*/
|
||||
bool lv_obj_get_drag(const lv_obj_t * obj);
|
||||
|
||||
@@ -1181,6 +1274,15 @@ bool lv_obj_get_drag_throw(const lv_obj_t * obj);
|
||||
*/
|
||||
bool lv_obj_get_drag_parent(const lv_obj_t * obj);
|
||||
|
||||
|
||||
/**
|
||||
* Get the focus parent attribute of an object
|
||||
* @param obj pointer to an object
|
||||
* @return true: focus parent is enabled
|
||||
*/
|
||||
bool lv_obj_get_focus_parent(const lv_obj_t * obj);
|
||||
|
||||
|
||||
/**
|
||||
* Get the drag parent attribute of an object
|
||||
* @param obj pointer to an object
|
||||
@@ -1312,6 +1414,13 @@ void * lv_obj_get_group(const lv_obj_t * obj);
|
||||
*/
|
||||
bool lv_obj_is_focused(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the really focused object by taking `focus_parent` into account.
|
||||
* @param obj the start object
|
||||
* @return the object to really focus
|
||||
*/
|
||||
lv_obj_t * lv_obj_get_focused_obj(const lv_obj_t * obj);
|
||||
|
||||
/*-------------------
|
||||
* OTHER FUNCTIONS
|
||||
*------------------*/
|
||||
@@ -1327,7 +1436,7 @@ lv_res_t lv_obj_handle_get_type_signal(lv_obj_type_t * buf, const char * name);
|
||||
/**
|
||||
* Initialize a rectangle descriptor from an object's styles
|
||||
* @param obj pointer to an object
|
||||
* @param type type of style. E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_STYLE_REL` or `LV_PAGE_STYLE_SCRL`
|
||||
* @param type type of style. E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_SLIDER_KOB`
|
||||
* @param draw_dsc the descriptor the initialize
|
||||
* @note Only the relevant fields will be set.
|
||||
* E.g. if `border width == 0` the other border properties won't be evaluated.
|
||||
@@ -1342,7 +1451,7 @@ void lv_obj_init_draw_line_dsc(lv_obj_t * obj, uint8_t part, lv_draw_line_dsc_t
|
||||
|
||||
/**
|
||||
* Get the required extra size (around the object's part) to draw shadow, outline, value etc.
|
||||
* @param obj poinr to an object
|
||||
* @param obj pointer to an object
|
||||
* @param part part of the object
|
||||
*/
|
||||
lv_coord_t lv_obj_get_draw_rect_ext_pad_size(lv_obj_t * obj, uint8_t part);
|
||||
@@ -1363,25 +1472,68 @@ void lv_obj_fade_in(lv_obj_t * obj, uint32_t time, uint32_t delay);
|
||||
*/
|
||||
void lv_obj_fade_out(lv_obj_t * obj, uint32_t time, uint32_t delay);
|
||||
|
||||
/**
|
||||
* Check if any object has a given type
|
||||
* @param obj pointer to an object
|
||||
* @param obj_type type of the object. (e.g. "lv_btn")
|
||||
* @return true: valid
|
||||
*/
|
||||
bool lv_debug_check_obj_type(const lv_obj_t * obj, const char * obj_type);
|
||||
|
||||
/**
|
||||
* Check if any object is still "alive", and part of the hierarchy
|
||||
* @param obj pointer to an object
|
||||
* @param obj_type type of the object. (e.g. "lv_btn")
|
||||
* @return true: valid
|
||||
*/
|
||||
bool lv_debug_check_obj_valid(const lv_obj_t * obj);
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Helps to quickly declare an event callback function.
|
||||
* Will be expanded to: `void <name> (lv_obj_t * obj, lv_event_t e)`
|
||||
* Will be expanded to: `static void <name> (lv_obj_t * obj, lv_event_t e)`
|
||||
*
|
||||
* Examples:
|
||||
* static LV_EVENT_CB_DECLARE(my_event1); //Protoype declaration
|
||||
* LV_EVENT_CB_DECLARE(my_event1); //Prototype declaration
|
||||
*
|
||||
* static LV_EVENT_CB_DECLARE(my_event1)
|
||||
* LV_EVENT_CB_DECLARE(my_event1)
|
||||
* {
|
||||
* if(e == LV_EVENT_CLICKED) {
|
||||
* lv_obj_set_hidden(obj ,true);
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
#define LV_EVENT_CB_DECLARE(name) void name(lv_obj_t * obj, lv_event_t e)
|
||||
#define LV_EVENT_CB_DECLARE(name) static void name(lv_obj_t * obj, lv_event_t e)
|
||||
|
||||
|
||||
#if LV_USE_DEBUG
|
||||
|
||||
# ifndef LV_DEBUG_IS_OBJ
|
||||
# define LV_DEBUG_IS_OBJ(obj_p, obj_type) (lv_debug_check_null(obj_p) && \
|
||||
lv_debug_check_obj_valid(obj_p) && \
|
||||
lv_debug_check_obj_type(obj_p, obj_type))
|
||||
# endif
|
||||
|
||||
|
||||
# if LV_USE_ASSERT_OBJ
|
||||
# ifndef LV_ASSERT_OBJ
|
||||
# define LV_ASSERT_OBJ(obj_p, obj_type) LV_DEBUG_ASSERT(LV_DEBUG_IS_OBJ(obj_p, obj_type), "Invalid object", obj_p);
|
||||
# endif
|
||||
# else /* LV_USE_ASSERT_OBJ == 0 */
|
||||
# if LV_USE_ASSERT_NULL /*Use at least LV_ASSERT_NULL if enabled*/
|
||||
# define LV_ASSERT_OBJ(obj_p, obj_type) LV_ASSERT_NULL(obj_p)
|
||||
# else
|
||||
# define LV_ASSERT_OBJ(obj_p, obj_type) true
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
# define LV_ASSERT_OBJ(obj, obj_type) true
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
@@ -95,20 +95,8 @@ extern "C" {
|
||||
}
|
||||
|
||||
#define _LV_OBJ_STYLE_SET_GET_DECLARE(prop_name, func_name, value_type, style_type, scalar) \
|
||||
_OBJ_GET_STYLE_##scalar(prop_name, func_name, value_type, style_type) \
|
||||
_OBJ_GET_STYLE_##scalar(prop_name, func_name, value_type, style_type) \
|
||||
_OBJ_SET_STYLE_LOCAL_##scalar(prop_name, func_name, value_type, style_type) \
|
||||
static inline void lv_obj_get_style_local_##func_name (lv_obj_t * obj, uint8_t part, lv_state_t state, void * res) \
|
||||
{ \
|
||||
_lv_style_get##style_type (lv_obj_get_local_style(obj, part), LV_STYLE_##prop_name | (state << LV_STYLE_STATE_POS), res); \
|
||||
} \
|
||||
static inline void lv_obj_remove_style_local_##func_name (lv_obj_t * obj, uint8_t part, lv_state_t state) \
|
||||
{ \
|
||||
_lv_obj_remove_style_local_prop(obj, part, LV_STYLE_##prop_name | (state << LV_STYLE_STATE_POS)); \
|
||||
} \
|
||||
static inline int16_t lv_style_get_##func_name (lv_style_t * style, lv_state_t state, void * res) \
|
||||
{ \
|
||||
return _lv_style_get##style_type (style, LV_STYLE_##prop_name | (state << LV_STYLE_STATE_POS), res); \
|
||||
} \
|
||||
_OBJ_SET_STYLE_##scalar(prop_name, func_name, value_type, style_type)
|
||||
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(RADIUS, radius, lv_style_int_t, _int, scalar)
|
||||
@@ -211,6 +199,102 @@ _LV_OBJ_STYLE_SET_GET_DECLARE(SCALE_END_COLOR, scale_end_color, lv_color_t, _col
|
||||
|
||||
#undef _LV_OBJ_STYLE_SET_GET_DECLARE
|
||||
|
||||
|
||||
static inline void lv_obj_set_style_local_pad_all(lv_obj_t * obj, uint8_t part, lv_state_t state, lv_style_int_t value)
|
||||
{
|
||||
lv_obj_set_style_local_pad_top(obj, part, state, value);
|
||||
lv_obj_set_style_local_pad_bottom(obj, part, state, value);
|
||||
lv_obj_set_style_local_pad_left(obj, part, state, value);
|
||||
lv_obj_set_style_local_pad_right(obj, part, state, value);
|
||||
}
|
||||
|
||||
|
||||
static inline void lv_style_set_pad_all(lv_style_t * style, lv_state_t state, lv_style_int_t value)
|
||||
{
|
||||
lv_style_set_pad_top(style, state, value);
|
||||
lv_style_set_pad_bottom(style, state, value);
|
||||
lv_style_set_pad_left(style, state, value);
|
||||
lv_style_set_pad_right(style, state, value);
|
||||
}
|
||||
|
||||
|
||||
static inline void lv_obj_set_style_local_pad_hor(lv_obj_t * obj, uint8_t part, lv_state_t state, lv_style_int_t value)
|
||||
{
|
||||
lv_obj_set_style_local_pad_left(obj, part, state, value);
|
||||
lv_obj_set_style_local_pad_right(obj, part, state, value);
|
||||
}
|
||||
|
||||
|
||||
static inline void lv_style_set_pad_hor(lv_style_t * style, lv_state_t state, lv_style_int_t value)
|
||||
{
|
||||
lv_style_set_pad_left(style, state, value);
|
||||
lv_style_set_pad_right(style, state, value);
|
||||
}
|
||||
|
||||
|
||||
static inline void lv_obj_set_style_local_pad_ver(lv_obj_t * obj, uint8_t part, lv_state_t state, lv_style_int_t value)
|
||||
{
|
||||
lv_obj_set_style_local_pad_top(obj, part, state, value);
|
||||
lv_obj_set_style_local_pad_bottom(obj, part, state, value);
|
||||
}
|
||||
|
||||
|
||||
static inline void lv_style_set_pad_ver(lv_style_t * style, lv_state_t state, lv_style_int_t value)
|
||||
{
|
||||
lv_style_set_pad_top(style, state, value);
|
||||
lv_style_set_pad_bottom(style, state, value);
|
||||
}
|
||||
|
||||
|
||||
static inline void lv_obj_set_style_local_margin_all(lv_obj_t * obj, uint8_t part, lv_state_t state,
|
||||
lv_style_int_t value)
|
||||
{
|
||||
lv_obj_set_style_local_margin_top(obj, part, state, value);
|
||||
lv_obj_set_style_local_margin_bottom(obj, part, state, value);
|
||||
lv_obj_set_style_local_margin_left(obj, part, state, value);
|
||||
lv_obj_set_style_local_margin_right(obj, part, state, value);
|
||||
}
|
||||
|
||||
|
||||
static inline void lv_style_set_margin_all(lv_style_t * style, lv_state_t state, lv_style_int_t value)
|
||||
{
|
||||
lv_style_set_margin_top(style, state, value);
|
||||
lv_style_set_margin_bottom(style, state, value);
|
||||
lv_style_set_margin_left(style, state, value);
|
||||
lv_style_set_margin_right(style, state, value);
|
||||
}
|
||||
|
||||
|
||||
static inline void lv_obj_set_style_local_margin_hor(lv_obj_t * obj, uint8_t part, lv_state_t state,
|
||||
lv_style_int_t value)
|
||||
{
|
||||
lv_obj_set_style_local_margin_left(obj, part, state, value);
|
||||
lv_obj_set_style_local_margin_right(obj, part, state, value);
|
||||
}
|
||||
|
||||
|
||||
static inline void lv_style_set_margin_hor(lv_style_t * style, lv_state_t state, lv_style_int_t value)
|
||||
{
|
||||
lv_style_set_margin_left(style, state, value);
|
||||
lv_style_set_margin_right(style, state, value);
|
||||
}
|
||||
|
||||
|
||||
static inline void lv_obj_set_style_local_margin_ver(lv_obj_t * obj, uint8_t part, lv_state_t state,
|
||||
lv_style_int_t value)
|
||||
{
|
||||
lv_obj_set_style_local_margin_top(obj, part, state, value);
|
||||
lv_obj_set_style_local_margin_bottom(obj, part, state, value);
|
||||
}
|
||||
|
||||
|
||||
static inline void lv_style_set_margin_ver(lv_style_t * style, lv_state_t state, lv_style_int_t value)
|
||||
{
|
||||
lv_style_set_margin_top(style, state, value);
|
||||
lv_style_set_margin_bottom(style, state, value);
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include "../lv_misc/lv_math.h"
|
||||
#include "../lv_misc/lv_gc.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
#include "../lv_font/lv_font_fmt_txt.h"
|
||||
#include "../lv_gpu/lv_gpu_stm32_dma2d.h"
|
||||
|
||||
#if LV_USE_PERF_MONITOR
|
||||
#include "../lv_widgets/lv_label.h"
|
||||
@@ -64,7 +66,7 @@ static lv_disp_t * disp_refr; /*Display being refreshed*/
|
||||
/**
|
||||
* Initialize the screen refresh subsystem
|
||||
*/
|
||||
void lv_refr_init(void)
|
||||
void _lv_refr_init(void)
|
||||
{
|
||||
/*Nothing to do*/
|
||||
}
|
||||
@@ -83,13 +85,13 @@ void lv_refr_now(lv_disp_t * disp)
|
||||
#endif
|
||||
|
||||
if(disp) {
|
||||
lv_disp_refr_task(disp->refr_task);
|
||||
_lv_disp_refr_task(disp->refr_task);
|
||||
}
|
||||
else {
|
||||
lv_disp_t * d;
|
||||
d = lv_disp_get_next(NULL);
|
||||
while(d) {
|
||||
lv_disp_refr_task(d->refr_task);
|
||||
_lv_disp_refr_task(d->refr_task);
|
||||
d = lv_disp_get_next(d);
|
||||
}
|
||||
}
|
||||
@@ -101,7 +103,7 @@ void lv_refr_now(lv_disp_t * disp)
|
||||
* @param disp pointer to display where the area should be invalidated (NULL can be used if there is
|
||||
* only one display)
|
||||
*/
|
||||
void lv_inv_area(lv_disp_t * disp, const lv_area_t * area_p)
|
||||
void _lv_inv_area(lv_disp_t * disp, const lv_area_t * area_p)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) return;
|
||||
@@ -121,7 +123,7 @@ void lv_inv_area(lv_disp_t * disp, const lv_area_t * area_p)
|
||||
lv_area_t com_area;
|
||||
bool suc;
|
||||
|
||||
suc = lv_area_intersect(&com_area, area_p, &scr_area);
|
||||
suc = _lv_area_intersect(&com_area, area_p, &scr_area);
|
||||
|
||||
/*The area is truncated to the screen*/
|
||||
if(suc != false) {
|
||||
@@ -130,7 +132,7 @@ void lv_inv_area(lv_disp_t * disp, const lv_area_t * area_p)
|
||||
/*Save only if this area is not in one of the saved areas*/
|
||||
uint16_t i;
|
||||
for(i = 0; i < disp->inv_p; i++) {
|
||||
if(lv_area_is_in(&com_area, &disp->inv_areas[i], 0) != false) return;
|
||||
if(_lv_area_is_in(&com_area, &disp->inv_areas[i], 0) != false) return;
|
||||
}
|
||||
|
||||
/*Save the area*/
|
||||
@@ -150,18 +152,18 @@ void lv_inv_area(lv_disp_t * disp, const lv_area_t * area_p)
|
||||
* Get the display which is being refreshed
|
||||
* @return the display being refreshed
|
||||
*/
|
||||
lv_disp_t * lv_refr_get_disp_refreshing(void)
|
||||
lv_disp_t * _lv_refr_get_disp_refreshing(void)
|
||||
{
|
||||
return disp_refr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the display which is being refreshed.
|
||||
* It shouldn1t be used directly by the user.
|
||||
* It shouldn't be used directly by the user.
|
||||
* It can be used to trick the drawing functions about there is an active display.
|
||||
* @param the display being refreshed
|
||||
*/
|
||||
void lv_refr_set_disp_refreshing(lv_disp_t * disp)
|
||||
void _lv_refr_set_disp_refreshing(lv_disp_t * disp)
|
||||
{
|
||||
disp_refr = disp;
|
||||
}
|
||||
@@ -170,7 +172,7 @@ void lv_refr_set_disp_refreshing(lv_disp_t * disp)
|
||||
* Called periodically to handle the refreshing
|
||||
* @param task pointer to the task itself
|
||||
*/
|
||||
void lv_disp_refr_task(lv_task_t * task)
|
||||
void _lv_disp_refr_task(lv_task_t * task)
|
||||
{
|
||||
LV_LOG_TRACE("lv_refr_task: started");
|
||||
|
||||
@@ -200,41 +202,65 @@ void lv_disp_refr_task(lv_task_t * task)
|
||||
if(disp_refr->inv_p != 0) {
|
||||
/* In true double buffered mode copy the refreshed areas to the new VDB to keep it up to date.
|
||||
* With set_px_cb we don't know anything about the buffer (even it's size) so skip copying.*/
|
||||
if(lv_disp_is_true_double_buf(disp_refr) && disp_refr->driver.set_px_cb == NULL) {
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);
|
||||
if(lv_disp_is_true_double_buf(disp_refr)) {
|
||||
if(disp_refr->driver.set_px_cb) {
|
||||
LV_LOG_WARN("Can't handle 2 screen sized buffers with set_px_cb. Display is not refreshed.");
|
||||
}
|
||||
else {
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);
|
||||
|
||||
/*Flush the content of the VDB*/
|
||||
lv_refr_vdb_flush();
|
||||
/*Flush the content of the VDB*/
|
||||
lv_refr_vdb_flush();
|
||||
|
||||
/* With true double buffering the flushing should be only the address change of the
|
||||
* current frame buffer. Wait until the address change is ready and copy the changed
|
||||
* content to the other frame buffer (new active VDB) to keep the buffers synchronized*/
|
||||
while(vdb->flushing)
|
||||
;
|
||||
/* With true double buffering the flushing should be only the address change of the
|
||||
* current frame buffer. Wait until the address change is ready and copy the changed
|
||||
* content to the other frame buffer (new active VDB) to keep the buffers synchronized*/
|
||||
while(vdb->flushing);
|
||||
|
||||
uint8_t * buf_act = (uint8_t *)vdb->buf_act;
|
||||
uint8_t * buf_ina = (uint8_t *)vdb->buf_act == vdb->buf1 ? vdb->buf2 : vdb->buf1;
|
||||
lv_color_t * copy_buf = NULL;
|
||||
#if LV_USE_GPU_STM32_DMA2D
|
||||
LV_UNUSED(copy_buf);
|
||||
#else
|
||||
copy_buf = _lv_mem_buf_get(disp_refr->driver.hor_res * sizeof(lv_color_t));
|
||||
#endif
|
||||
|
||||
lv_coord_t hres = lv_disp_get_hor_res(disp_refr);
|
||||
uint16_t a;
|
||||
for(a = 0; a < disp_refr->inv_p; a++) {
|
||||
if(disp_refr->inv_area_joined[a] == 0) {
|
||||
lv_coord_t y;
|
||||
uint32_t start_offs =
|
||||
(hres * disp_refr->inv_areas[a].y1 + disp_refr->inv_areas[a].x1) * sizeof(lv_color_t);
|
||||
uint32_t line_length = lv_area_get_width(&disp_refr->inv_areas[a]) * sizeof(lv_color_t);
|
||||
uint8_t * buf_act = (uint8_t *)vdb->buf_act;
|
||||
uint8_t * buf_ina = (uint8_t *)vdb->buf_act == vdb->buf1 ? vdb->buf2 : vdb->buf1;
|
||||
|
||||
for(y = disp_refr->inv_areas[a].y1; y <= disp_refr->inv_areas[a].y2; y++) {
|
||||
lv_memcpy(buf_act + start_offs, buf_ina + start_offs, line_length);
|
||||
start_offs += hres * sizeof(lv_color_t);
|
||||
lv_coord_t hres = lv_disp_get_hor_res(disp_refr);
|
||||
uint16_t a;
|
||||
for(a = 0; a < disp_refr->inv_p; a++) {
|
||||
if(disp_refr->inv_area_joined[a] == 0) {
|
||||
uint32_t start_offs =
|
||||
(hres * disp_refr->inv_areas[a].y1 + disp_refr->inv_areas[a].x1) * sizeof(lv_color_t);
|
||||
#if LV_USE_GPU_STM32_DMA2D
|
||||
lv_gpu_stm32_dma2d_copy((lv_color_t *)(buf_act + start_offs), disp_refr->driver.hor_res,
|
||||
(lv_color_t *)(buf_ina + start_offs), disp_refr->driver.hor_res,
|
||||
lv_area_get_width(&disp_refr->inv_areas[a]),
|
||||
lv_area_get_height(&disp_refr->inv_areas[a]));
|
||||
#else
|
||||
|
||||
lv_coord_t y;
|
||||
uint32_t line_length = lv_area_get_width(&disp_refr->inv_areas[a]) * sizeof(lv_color_t);
|
||||
|
||||
for(y = disp_refr->inv_areas[a].y1; y <= disp_refr->inv_areas[a].y2; y++) {
|
||||
/* The frame buffer is probably in an external RAM where sequential access is much faster.
|
||||
* So first copy a line into a buffer and write it back the ext. RAM */
|
||||
_lv_memcpy(copy_buf, buf_ina + start_offs, line_length);
|
||||
_lv_memcpy(buf_act + start_offs, copy_buf, line_length);
|
||||
start_offs += hres * sizeof(lv_color_t);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if(copy_buf) _lv_mem_buf_release(copy_buf);
|
||||
}
|
||||
} /*End of true double buffer handling*/
|
||||
|
||||
/*Clean up*/
|
||||
lv_memset_00(disp_refr->inv_areas, sizeof(disp_refr->inv_areas));
|
||||
lv_memset_00(disp_refr->inv_area_joined, sizeof(disp_refr->inv_area_joined));
|
||||
_lv_memset_00(disp_refr->inv_areas, sizeof(disp_refr->inv_areas));
|
||||
_lv_memset_00(disp_refr->inv_area_joined, sizeof(disp_refr->inv_area_joined));
|
||||
disp_refr->inv_p = 0;
|
||||
|
||||
elaps = lv_tick_elaps(start);
|
||||
@@ -244,7 +270,8 @@ void lv_disp_refr_task(lv_task_t * task)
|
||||
}
|
||||
}
|
||||
|
||||
lv_mem_buf_free_all();
|
||||
_lv_mem_buf_free_all();
|
||||
_lv_font_clean_up_fmt_txt();
|
||||
|
||||
#if LV_USE_PERF_MONITOR && LV_USE_LABEL
|
||||
static lv_obj_t * perf_label = NULL;
|
||||
@@ -306,11 +333,11 @@ static void lv_refr_join_area(void)
|
||||
}
|
||||
|
||||
/*Check if the areas are on each other*/
|
||||
if(lv_area_is_on(&disp_refr->inv_areas[join_in], &disp_refr->inv_areas[join_from]) == false) {
|
||||
if(_lv_area_is_on(&disp_refr->inv_areas[join_in], &disp_refr->inv_areas[join_from]) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
lv_area_join(&joined_area, &disp_refr->inv_areas[join_in], &disp_refr->inv_areas[join_from]);
|
||||
_lv_area_join(&joined_area, &disp_refr->inv_areas[join_in], &disp_refr->inv_areas[join_from]);
|
||||
|
||||
/*Join two area only if the joined area size is smaller*/
|
||||
if(lv_area_get_size(&joined_area) < (lv_area_get_size(&disp_refr->inv_areas[join_in]) +
|
||||
@@ -338,8 +365,8 @@ static void lv_refr_areas(void)
|
||||
int32_t last_i = 0;
|
||||
for(i = disp_refr->inv_p - 1; i >= 0; i--) {
|
||||
if(disp_refr->inv_area_joined[i] == 0) {
|
||||
last_i = i;
|
||||
break;
|
||||
last_i = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,8 +377,8 @@ static void lv_refr_areas(void)
|
||||
/*Refresh the unjoined areas*/
|
||||
if(disp_refr->inv_area_joined[i] == 0) {
|
||||
|
||||
if(i == last_i) disp_refr->driver.buffer->last_area = 1;
|
||||
disp_refr->driver.buffer->last_part = 0;
|
||||
if(i == last_i) disp_refr->driver.buffer->last_area = 1;
|
||||
disp_refr->driver.buffer->last_part = 0;
|
||||
lv_refr_area(&disp_refr->inv_areas[i]);
|
||||
|
||||
if(disp_refr->driver.monitor_cb) px_num += lv_area_get_size(&disp_refr->inv_areas[i]);
|
||||
@@ -383,7 +410,7 @@ static void lv_refr_area(const lv_area_t * area_p)
|
||||
lv_coord_t w = lv_area_get_width(area_p);
|
||||
lv_coord_t h = lv_area_get_height(area_p);
|
||||
lv_coord_t y2 =
|
||||
area_p->y2 >= lv_disp_get_ver_res(disp_refr) ? y2 = lv_disp_get_ver_res(disp_refr) - 1 : area_p->y2;
|
||||
area_p->y2 >= lv_disp_get_ver_res(disp_refr) ? lv_disp_get_ver_res(disp_refr) - 1 : area_p->y2;
|
||||
|
||||
int32_t max_row = (uint32_t)vdb->size / w;
|
||||
|
||||
@@ -463,18 +490,64 @@ static void lv_refr_area_part(const lv_area_t * area_p)
|
||||
}
|
||||
}
|
||||
|
||||
lv_obj_t * top_p;
|
||||
lv_obj_t * top_act_scr = NULL;
|
||||
lv_obj_t * top_prev_scr = NULL;
|
||||
|
||||
/*Get the new mask from the original area and the act. VDB
|
||||
It will be a part of 'area_p'*/
|
||||
lv_area_t start_mask;
|
||||
lv_area_intersect(&start_mask, area_p, &vdb->area);
|
||||
_lv_area_intersect(&start_mask, area_p, &vdb->area);
|
||||
|
||||
/*Get the most top object which is not covered by others*/
|
||||
top_p = lv_refr_get_top_obj(&start_mask, lv_disp_get_scr_act(disp_refr));
|
||||
top_act_scr = lv_refr_get_top_obj(&start_mask, lv_disp_get_scr_act(disp_refr));
|
||||
if(disp_refr->prev_scr) {
|
||||
top_prev_scr = lv_refr_get_top_obj(&start_mask, disp_refr->prev_scr);
|
||||
}
|
||||
|
||||
/*Draw a display background if there is no top object*/
|
||||
if(top_act_scr == NULL && top_prev_scr == NULL) {
|
||||
if(disp_refr->bg_img) {
|
||||
lv_draw_img_dsc_t dsc;
|
||||
lv_draw_img_dsc_init(&dsc);
|
||||
dsc.opa = disp_refr->bg_opa;
|
||||
lv_img_header_t header;
|
||||
lv_res_t res;
|
||||
res = lv_img_decoder_get_info(disp_refr->bg_img, &header);
|
||||
if(res == LV_RES_OK) {
|
||||
lv_area_t a;
|
||||
lv_area_set(&a, 0, 0, header.w - 1, header.h - 1);
|
||||
lv_draw_img(&a, &start_mask, disp_refr->bg_img, &dsc);
|
||||
}
|
||||
else {
|
||||
LV_LOG_WARN("Can't draw the background image")
|
||||
}
|
||||
}
|
||||
else {
|
||||
lv_draw_rect_dsc_t dsc;
|
||||
lv_draw_rect_dsc_init(&dsc);
|
||||
dsc.bg_color = disp_refr->bg_color;
|
||||
dsc.bg_opa = disp_refr->bg_opa;
|
||||
lv_draw_rect(&start_mask, &start_mask, &dsc);
|
||||
|
||||
}
|
||||
}
|
||||
/*Refresh the previous screen if any*/
|
||||
if(disp_refr->prev_scr) {
|
||||
/*Get the most top object which is not covered by others*/
|
||||
if(top_prev_scr == NULL) {
|
||||
top_prev_scr = disp_refr->prev_scr;
|
||||
}
|
||||
/*Do the refreshing from the top object*/
|
||||
lv_refr_obj_and_children(top_prev_scr, &start_mask);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(top_act_scr == NULL) {
|
||||
top_act_scr = disp_refr->act_scr;
|
||||
}
|
||||
/*Do the refreshing from the top object*/
|
||||
lv_refr_obj_and_children(top_p, &start_mask);
|
||||
lv_refr_obj_and_children(top_act_scr, &start_mask);
|
||||
|
||||
/*Also refresh top and sys layer unconditionally*/
|
||||
lv_refr_obj_and_children(lv_disp_get_layer_top(disp_refr), &start_mask);
|
||||
@@ -498,13 +571,18 @@ static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj)
|
||||
lv_obj_t * found_p = NULL;
|
||||
|
||||
/*If this object is fully cover the draw area check the children too */
|
||||
if(lv_area_is_in(area_p, &obj->coords, 0) && obj->hidden == 0) {
|
||||
lv_design_res_t design_res = obj->design_cb ? obj->design_cb(obj, area_p,
|
||||
LV_DESIGN_COVER_CHK) : LV_DESIGN_RES_NOT_COVER;
|
||||
if(_lv_area_is_in(area_p, &obj->coords, 0) && obj->hidden == 0) {
|
||||
lv_design_res_t design_res = obj->design_cb(obj, area_p, LV_DESIGN_COVER_CHK);
|
||||
if(design_res == LV_DESIGN_RES_MASKED) return NULL;
|
||||
|
||||
#if LV_USE_OPA_SCALE
|
||||
if(design_res == LV_DESIGN_RES_COVER && lv_obj_get_style_opa_scale(obj, LV_OBJ_PART_MAIN) != LV_OPA_COVER) {
|
||||
design_res = LV_DESIGN_RES_NOT_COVER;
|
||||
}
|
||||
#endif
|
||||
|
||||
lv_obj_t * i;
|
||||
LV_LL_READ(obj->child_ll, i) {
|
||||
_LV_LL_READ(obj->child_ll, i) {
|
||||
found_p = lv_refr_get_top_obj(area_p, i);
|
||||
|
||||
/*If a children is ok then break*/
|
||||
@@ -549,12 +627,12 @@ static void lv_refr_obj_and_children(lv_obj_t * top_p, const lv_area_t * mask_p)
|
||||
/*Do until not reach the screen*/
|
||||
while(par != NULL) {
|
||||
/*object before border_p has to be redrawn*/
|
||||
lv_obj_t * i = lv_ll_get_prev(&(par->child_ll), border_p);
|
||||
lv_obj_t * i = _lv_ll_get_prev(&(par->child_ll), border_p);
|
||||
|
||||
while(i != NULL) {
|
||||
/*Refresh the objects*/
|
||||
lv_refr_obj(i, mask_p);
|
||||
i = lv_ll_get_prev(&(par->child_ll), i);
|
||||
i = _lv_ll_get_prev(&(par->child_ll), i);
|
||||
}
|
||||
|
||||
/*Call the post draw design function of the parents of the to object*/
|
||||
@@ -590,7 +668,7 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
|
||||
obj_area.y1 -= ext_size;
|
||||
obj_area.x2 += ext_size;
|
||||
obj_area.y2 += ext_size;
|
||||
union_ok = lv_area_intersect(&obj_ext_mask, mask_ori_p, &obj_area);
|
||||
union_ok = _lv_area_intersect(&obj_ext_mask, mask_ori_p, &obj_area);
|
||||
|
||||
/*Draw the parent and its children only if they ore on 'mask_parent'*/
|
||||
if(union_ok != false) {
|
||||
@@ -617,12 +695,12 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
|
||||
#endif
|
||||
/*Create a new 'obj_mask' without 'ext_size' because the children can't be visible there*/
|
||||
lv_obj_get_coords(obj, &obj_area);
|
||||
union_ok = lv_area_intersect(&obj_mask, mask_ori_p, &obj_area);
|
||||
union_ok = _lv_area_intersect(&obj_mask, mask_ori_p, &obj_area);
|
||||
if(union_ok != false) {
|
||||
lv_area_t mask_child; /*Mask from obj and its child*/
|
||||
lv_obj_t * child_p;
|
||||
lv_area_t child_area;
|
||||
LV_LL_READ_BACK(obj->child_ll, child_p) {
|
||||
_LV_LL_READ_BACK(obj->child_ll, child_p) {
|
||||
lv_obj_get_coords(child_p, &child_area);
|
||||
ext_size = child_p->ext_draw_pad;
|
||||
child_area.x1 -= ext_size;
|
||||
@@ -631,7 +709,7 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
|
||||
child_area.y2 += ext_size;
|
||||
/* Get the union (common parts) of original mask (from obj)
|
||||
* and its child */
|
||||
union_ok = lv_area_intersect(&mask_child, &obj_mask, &child_area);
|
||||
union_ok = _lv_area_intersect(&mask_child, &obj_mask, &child_area);
|
||||
|
||||
/*If the parent and the child has common area then refresh the child */
|
||||
if(union_ok) {
|
||||
@@ -667,7 +745,7 @@ static void lv_refr_vdb_flush(void)
|
||||
else vdb->flushing_last = 0;
|
||||
|
||||
/*Flush the rendered content to the display*/
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
if(disp->driver.flush_cb) disp->driver.flush_cb(&disp->driver, &vdb->area, vdb->buf_act);
|
||||
|
||||
if(vdb->buf1 && vdb->buf2) {
|
||||
|
||||
@@ -45,7 +45,7 @@ extern "C" {
|
||||
/**
|
||||
* Initialize the screen refresh subsystem
|
||||
*/
|
||||
void lv_refr_init(void);
|
||||
void _lv_refr_init(void);
|
||||
|
||||
/**
|
||||
* Redraw the invalidated areas now.
|
||||
@@ -62,27 +62,27 @@ void lv_refr_now(lv_disp_t * disp);
|
||||
* @param disp pointer to display where the area should be invalidated (NULL can be used if there is
|
||||
* only one display)
|
||||
*/
|
||||
void lv_inv_area(lv_disp_t * disp, const lv_area_t * area_p);
|
||||
void _lv_inv_area(lv_disp_t * disp, const lv_area_t * area_p);
|
||||
|
||||
/**
|
||||
* Get the display which is being refreshed
|
||||
* @return the display being refreshed
|
||||
*/
|
||||
lv_disp_t * lv_refr_get_disp_refreshing(void);
|
||||
lv_disp_t * _lv_refr_get_disp_refreshing(void);
|
||||
|
||||
/**
|
||||
* Set the display which is being refreshed.
|
||||
* It shouldn1t be used directly by the user.
|
||||
* It shouldn't be used directly by the user.
|
||||
* It can be used to trick the drawing functions about there is an active display.
|
||||
* @param the display being refreshed
|
||||
*/
|
||||
void lv_refr_set_disp_refreshing(lv_disp_t * disp);
|
||||
void _lv_refr_set_disp_refreshing(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Called periodically to handle the refreshing
|
||||
* @param task pointer to the task itself
|
||||
*/
|
||||
void lv_disp_refr_task(lv_task_t * task);
|
||||
void _lv_disp_refr_task(lv_task_t * task);
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj.h"
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "../lv_misc/lv_mem.h"
|
||||
#include "../lv_misc/lv_anim.h"
|
||||
|
||||
@@ -37,6 +36,12 @@
|
||||
**********************/
|
||||
LV_ATTRIBUTE_FAST_MEM static inline int32_t get_property_index(const lv_style_t * style, lv_style_property_t prop);
|
||||
static lv_style_t * get_alloc_local_style(lv_style_list_t * list);
|
||||
static inline void style_resize(lv_style_t * style, size_t sz);
|
||||
static inline lv_style_property_t get_style_prop(const lv_style_t * style, size_t idx);
|
||||
static inline uint8_t get_style_prop_id(const lv_style_t * style, size_t idx);
|
||||
static inline uint8_t get_style_prop_attr(const lv_style_t * style, size_t idx);
|
||||
static inline size_t get_prop_size(uint8_t prop_id);
|
||||
static inline size_t get_next_prop_index(uint8_t prop_id, size_t id);
|
||||
|
||||
/**********************
|
||||
* GLOABAL VARIABLES
|
||||
@@ -60,7 +65,7 @@ static lv_style_t * get_alloc_local_style(lv_style_list_t * list);
|
||||
*/
|
||||
void lv_style_init(lv_style_t * style)
|
||||
{
|
||||
lv_memset_00(style, sizeof(lv_style_t));
|
||||
_lv_memset_00(style, sizeof(lv_style_t));
|
||||
#if LV_USE_ASSERT_STYLE
|
||||
style->sentinel = LV_DEBUG_STYLE_SENTINEL_VALUE;
|
||||
#endif
|
||||
@@ -80,9 +85,9 @@ void lv_style_copy(lv_style_t * style_dest, const lv_style_t * style_src)
|
||||
|
||||
if(style_src->map == NULL) return;
|
||||
|
||||
uint16_t size = lv_style_get_mem_size(style_src);
|
||||
uint16_t size = _lv_style_get_mem_size(style_src);
|
||||
style_dest->map = lv_mem_alloc(size);
|
||||
lv_memcpy(style_dest->map, style_src->map, size);
|
||||
_lv_memcpy(style_dest->map, style_src->map, size);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,16 +108,12 @@ bool lv_style_remove_prop(lv_style_t * style, lv_style_property_t prop)
|
||||
lv_style_attr_t attr_found;
|
||||
lv_style_attr_t attr_goal;
|
||||
|
||||
attr_found.full = *(style->map + id + 1);
|
||||
attr_goal.full = (prop >> 8) & 0xFFU;
|
||||
attr_found = get_style_prop_attr(style, id);
|
||||
attr_goal = (prop >> 8) & 0xFFU;
|
||||
|
||||
if(attr_found.bits.state == attr_goal.bits.state) {
|
||||
uint32_t map_size = lv_style_get_mem_size(style);
|
||||
uint8_t prop_size = sizeof(lv_style_property_t);
|
||||
if((prop & 0xF) < LV_STYLE_ID_COLOR) prop_size += sizeof(lv_style_int_t);
|
||||
else if((prop & 0xF) < LV_STYLE_ID_OPA) prop_size += sizeof(lv_color_t);
|
||||
else if((prop & 0xF) < LV_STYLE_ID_PTR) prop_size += sizeof(lv_opa_t);
|
||||
else prop_size += sizeof(const void *);
|
||||
if(LV_STYLE_ATTR_GET_STATE(attr_found) == LV_STYLE_ATTR_GET_STATE(attr_goal)) {
|
||||
uint32_t map_size = _lv_style_get_mem_size(style);
|
||||
uint8_t prop_size = get_prop_size(prop);
|
||||
|
||||
/*Move the props to fill the space of the property to delete*/
|
||||
uint32_t i;
|
||||
@@ -120,7 +121,7 @@ bool lv_style_remove_prop(lv_style_t * style, lv_style_property_t prop)
|
||||
style->map[i] = style->map[i + prop_size];
|
||||
}
|
||||
|
||||
style->map = lv_mem_realloc(style->map, map_size - prop_size);
|
||||
style_resize(style, map_size - prop_size);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -135,7 +136,7 @@ bool lv_style_remove_prop(lv_style_t * style, lv_style_property_t prop)
|
||||
*/
|
||||
void lv_style_list_init(lv_style_list_t * list)
|
||||
{
|
||||
lv_memset_00(list, sizeof(lv_style_list_t));
|
||||
_lv_memset_00(list, sizeof(lv_style_list_t));
|
||||
#if LV_USE_ASSERT_STYLE
|
||||
list->sentinel = LV_DEBUG_STYLE_LIST_SENTINEL_VALUE;
|
||||
#endif
|
||||
@@ -151,7 +152,7 @@ void lv_style_list_copy(lv_style_list_t * list_dest, const lv_style_list_t * lis
|
||||
LV_ASSERT_STYLE_LIST(list_dest);
|
||||
LV_ASSERT_STYLE_LIST(list_src);
|
||||
|
||||
lv_style_list_reset(list_dest);
|
||||
_lv_style_list_reset(list_dest);
|
||||
|
||||
if(list_src->style_list == NULL) return;
|
||||
|
||||
@@ -159,24 +160,24 @@ void lv_style_list_copy(lv_style_list_t * list_dest, const lv_style_list_t * lis
|
||||
if(list_src->has_local == 0) {
|
||||
if(list_src->has_trans) {
|
||||
list_dest->style_list = lv_mem_alloc((list_src->style_cnt - 1) * sizeof(lv_style_t *));
|
||||
lv_memcpy(list_dest->style_list, list_src->style_list + 1, (list_src->style_cnt - 1) * sizeof(lv_style_t *));
|
||||
_lv_memcpy(list_dest->style_list, list_src->style_list + 1, (list_src->style_cnt - 1) * sizeof(lv_style_t *));
|
||||
list_dest->style_cnt = list_src->style_cnt - 1;
|
||||
}
|
||||
else {
|
||||
list_dest->style_list = lv_mem_alloc(list_src->style_cnt * sizeof(lv_style_t *));
|
||||
lv_memcpy(list_dest->style_list, list_src->style_list, list_src->style_cnt * sizeof(lv_style_t *));
|
||||
_lv_memcpy(list_dest->style_list, list_src->style_list, list_src->style_cnt * sizeof(lv_style_t *));
|
||||
list_dest->style_cnt = list_src->style_cnt;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(list_src->has_trans) {
|
||||
list_dest->style_list = lv_mem_alloc((list_src->style_cnt - 2) * sizeof(lv_style_t *));
|
||||
lv_memcpy(list_dest->style_list, list_src->style_list + 2, (list_src->style_cnt - 2) * sizeof(lv_style_t *));
|
||||
_lv_memcpy(list_dest->style_list, list_src->style_list + 2, (list_src->style_cnt - 2) * sizeof(lv_style_t *));
|
||||
list_dest->style_cnt = list_src->style_cnt - 2;
|
||||
}
|
||||
else {
|
||||
list_dest->style_list = lv_mem_alloc((list_src->style_cnt - 1) * sizeof(lv_style_t *));
|
||||
lv_memcpy(list_dest->style_list, list_src->style_list + 1, (list_src->style_cnt - 1) * sizeof(lv_style_t *));
|
||||
_lv_memcpy(list_dest->style_list, list_src->style_list + 1, (list_src->style_cnt - 1) * sizeof(lv_style_t *));
|
||||
list_dest->style_cnt = list_src->style_cnt - 1;
|
||||
}
|
||||
|
||||
@@ -192,7 +193,7 @@ void lv_style_list_copy(lv_style_list_t * list_dest, const lv_style_list_t * lis
|
||||
* @param list pointer to a style list
|
||||
* @param style pointer to a style to add
|
||||
*/
|
||||
void lv_style_list_add_style(lv_style_list_t * list, lv_style_t * style)
|
||||
void _lv_style_list_add_style(lv_style_list_t * list, lv_style_t * style)
|
||||
{
|
||||
LV_ASSERT_STYLE_LIST(list);
|
||||
LV_ASSERT_STYLE(style);
|
||||
@@ -200,7 +201,7 @@ void lv_style_list_add_style(lv_style_list_t * list, lv_style_t * style)
|
||||
if(list == NULL) return;
|
||||
|
||||
/*Remove the style first if already exists*/
|
||||
lv_style_list_remove_style(list, style);
|
||||
_lv_style_list_remove_style(list, style);
|
||||
|
||||
lv_style_t ** new_classes;
|
||||
if(list->style_cnt == 0) new_classes = lv_mem_alloc(sizeof(lv_style_t *));
|
||||
@@ -230,7 +231,7 @@ void lv_style_list_add_style(lv_style_list_t * list, lv_style_t * style)
|
||||
* @param style_list pointer to a style list
|
||||
* @param style pointer to a style to remove
|
||||
*/
|
||||
void lv_style_list_remove_style(lv_style_list_t * list, lv_style_t * style)
|
||||
void _lv_style_list_remove_style(lv_style_list_t * list, lv_style_t * style)
|
||||
{
|
||||
LV_ASSERT_STYLE_LIST(list);
|
||||
LV_ASSERT_STYLE(style);
|
||||
@@ -256,7 +257,7 @@ void lv_style_list_remove_style(lv_style_list_t * list, lv_style_t * style)
|
||||
return;
|
||||
}
|
||||
|
||||
lv_style_t ** new_classes = lv_mem_realloc(list->style_list, sizeof(lv_style_t *) * (list->style_cnt - 1));
|
||||
lv_style_t ** new_classes = lv_mem_alloc(sizeof(lv_style_t *) * (list->style_cnt - 1));
|
||||
LV_ASSERT_MEM(new_classes);
|
||||
if(new_classes == NULL) {
|
||||
LV_LOG_WARN("lv_style_list_remove_style: couldn't reallocate class list");
|
||||
@@ -270,6 +271,8 @@ void lv_style_list_remove_style(lv_style_list_t * list, lv_style_t * style)
|
||||
|
||||
}
|
||||
|
||||
lv_mem_free(list->style_list);
|
||||
|
||||
list->style_cnt--;
|
||||
list->style_list = new_classes;
|
||||
}
|
||||
@@ -279,7 +282,7 @@ void lv_style_list_remove_style(lv_style_list_t * list, lv_style_t * style)
|
||||
* Leave `ignore_trans` flag as it is.
|
||||
* @param list pointer to a style list.
|
||||
*/
|
||||
void lv_style_list_reset(lv_style_list_t * list)
|
||||
void _lv_style_list_reset(lv_style_list_t * list)
|
||||
{
|
||||
LV_ASSERT_STYLE_LIST(list);
|
||||
|
||||
@@ -294,7 +297,7 @@ void lv_style_list_reset(lv_style_list_t * list)
|
||||
}
|
||||
|
||||
if(list->has_trans) {
|
||||
lv_style_t * trans = lv_style_list_get_transition_style(list);
|
||||
lv_style_t * trans = _lv_style_list_get_transition_style(list);
|
||||
if(trans) {
|
||||
lv_style_reset(trans);
|
||||
lv_mem_free(trans);
|
||||
@@ -329,21 +332,16 @@ void lv_style_reset(lv_style_t * style)
|
||||
* @param style pointer to a style
|
||||
* @return size of the properties in bytes
|
||||
*/
|
||||
uint16_t lv_style_get_mem_size(const lv_style_t * style)
|
||||
uint16_t _lv_style_get_mem_size(const lv_style_t * style)
|
||||
{
|
||||
LV_ASSERT_STYLE(style);
|
||||
|
||||
if(style->map == NULL) return 0;
|
||||
|
||||
size_t i = 0;
|
||||
while(style->map[i] != _LV_STYLE_CLOSEING_PROP) {
|
||||
/*Go to the next property*/
|
||||
if((style->map[i] & 0xF) < LV_STYLE_ID_COLOR) i += sizeof(lv_style_int_t);
|
||||
else if((style->map[i] & 0xF) < LV_STYLE_ID_OPA) i += sizeof(lv_color_t);
|
||||
else if((style->map[i] & 0xF) < LV_STYLE_ID_PTR) i += sizeof(lv_opa_t);
|
||||
else i += sizeof(const void *);
|
||||
|
||||
i += sizeof(lv_style_property_t);
|
||||
uint8_t prop_id;
|
||||
while((prop_id = get_style_prop_id(style, i)) != _LV_STYLE_CLOSEING_PROP) {
|
||||
i = get_next_prop_index(prop_id, i);
|
||||
}
|
||||
|
||||
return i + sizeof(lv_style_property_t);
|
||||
@@ -369,11 +367,11 @@ void _lv_style_set_int(lv_style_t * style, lv_style_property_t prop, lv_style_in
|
||||
lv_style_attr_t attr_found;
|
||||
lv_style_attr_t attr_goal;
|
||||
|
||||
attr_found.full = *(style->map + id + 1);
|
||||
attr_goal.full = (prop >> 8) & 0xFFU;
|
||||
attr_found = get_style_prop_attr(style, id);
|
||||
attr_goal = (prop >> 8) & 0xFFU;
|
||||
|
||||
if(attr_found.bits.state == attr_goal.bits.state) {
|
||||
lv_memcpy_small(style->map + id + sizeof(lv_style_property_t), &value, sizeof(lv_style_int_t));
|
||||
if(LV_STYLE_ATTR_GET_STATE(attr_found) == LV_STYLE_ATTR_GET_STATE(attr_goal)) {
|
||||
_lv_memcpy_small(style->map + id + sizeof(lv_style_property_t), &value, sizeof(lv_style_int_t));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -383,16 +381,16 @@ void _lv_style_set_int(lv_style_t * style, lv_style_property_t prop, lv_style_in
|
||||
lv_style_property_t end_mark = _LV_STYLE_CLOSEING_PROP;
|
||||
uint8_t end_mark_size = sizeof(end_mark);
|
||||
|
||||
uint16_t size = lv_style_get_mem_size(style);
|
||||
uint16_t size = _lv_style_get_mem_size(style);
|
||||
if(size == 0) size += end_mark_size;
|
||||
size += sizeof(lv_style_property_t) + sizeof(lv_style_int_t);
|
||||
style->map = lv_mem_realloc(style->map, size);
|
||||
style_resize(style, size);
|
||||
LV_ASSERT_MEM(style->map);
|
||||
if(style == NULL) return;
|
||||
|
||||
lv_memcpy_small(style->map + size - new_prop_size - end_mark_size, &prop, sizeof(lv_style_property_t));
|
||||
lv_memcpy_small(style->map + size - sizeof(lv_style_int_t) - end_mark_size, &value, sizeof(lv_style_int_t));
|
||||
lv_memcpy_small(style->map + size - end_mark_size, &end_mark, sizeof(end_mark));
|
||||
_lv_memcpy_small(style->map + size - new_prop_size - end_mark_size, &prop, sizeof(lv_style_property_t));
|
||||
_lv_memcpy_small(style->map + size - sizeof(lv_style_int_t) - end_mark_size, &value, sizeof(lv_style_int_t));
|
||||
_lv_memcpy_small(style->map + size - end_mark_size, &end_mark, sizeof(end_mark));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -415,11 +413,11 @@ void _lv_style_set_color(lv_style_t * style, lv_style_property_t prop, lv_color_
|
||||
lv_style_attr_t attr_found;
|
||||
lv_style_attr_t attr_goal;
|
||||
|
||||
attr_found.full = *(style->map + id + 1);
|
||||
attr_goal.full = (prop >> 8) & 0xFFU;
|
||||
attr_found = get_style_prop_attr(style, id);
|
||||
attr_goal = (prop >> 8) & 0xFFU;
|
||||
|
||||
if(attr_found.bits.state == attr_goal.bits.state) {
|
||||
lv_memcpy_small(style->map + id + sizeof(lv_style_property_t), &color, sizeof(lv_color_t));
|
||||
if(LV_STYLE_ATTR_GET_STATE(attr_found) == LV_STYLE_ATTR_GET_STATE(attr_goal)) {
|
||||
_lv_memcpy_small(style->map + id + sizeof(lv_style_property_t), &color, sizeof(lv_color_t));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -429,17 +427,17 @@ void _lv_style_set_color(lv_style_t * style, lv_style_property_t prop, lv_color_
|
||||
lv_style_property_t end_mark = _LV_STYLE_CLOSEING_PROP;
|
||||
uint8_t end_mark_size = sizeof(end_mark);
|
||||
|
||||
uint16_t size = lv_style_get_mem_size(style);
|
||||
uint16_t size = _lv_style_get_mem_size(style);
|
||||
if(size == 0) size += end_mark_size;
|
||||
|
||||
size += sizeof(lv_style_property_t) + sizeof(lv_color_t);
|
||||
style->map = lv_mem_realloc(style->map, size);
|
||||
style_resize(style, size);
|
||||
LV_ASSERT_MEM(style->map);
|
||||
if(style == NULL) return;
|
||||
|
||||
lv_memcpy_small(style->map + size - new_prop_size - end_mark_size, &prop, sizeof(lv_style_property_t));
|
||||
lv_memcpy_small(style->map + size - sizeof(lv_color_t) - end_mark_size, &color, sizeof(lv_color_t));
|
||||
lv_memcpy_small(style->map + size - end_mark_size, &end_mark, sizeof(end_mark));
|
||||
_lv_memcpy_small(style->map + size - new_prop_size - end_mark_size, &prop, sizeof(lv_style_property_t));
|
||||
_lv_memcpy_small(style->map + size - sizeof(lv_color_t) - end_mark_size, &color, sizeof(lv_color_t));
|
||||
_lv_memcpy_small(style->map + size - end_mark_size, &end_mark, sizeof(end_mark));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -462,11 +460,11 @@ void _lv_style_set_opa(lv_style_t * style, lv_style_property_t prop, lv_opa_t op
|
||||
lv_style_attr_t attr_found;
|
||||
lv_style_attr_t attr_goal;
|
||||
|
||||
attr_found.full = *(style->map + id + 1);
|
||||
attr_goal.full = (prop >> 8) & 0xFFU;
|
||||
attr_found = get_style_prop_attr(style, id);
|
||||
attr_goal = (prop >> 8) & 0xFFU;
|
||||
|
||||
if(attr_found.bits.state == attr_goal.bits.state) {
|
||||
lv_memcpy_small(style->map + id + sizeof(lv_style_property_t), &opa, sizeof(lv_opa_t));
|
||||
if(LV_STYLE_ATTR_GET_STATE(attr_found) == LV_STYLE_ATTR_GET_STATE(attr_goal)) {
|
||||
_lv_memcpy_small(style->map + id + sizeof(lv_style_property_t), &opa, sizeof(lv_opa_t));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -476,17 +474,17 @@ void _lv_style_set_opa(lv_style_t * style, lv_style_property_t prop, lv_opa_t op
|
||||
lv_style_property_t end_mark = _LV_STYLE_CLOSEING_PROP;
|
||||
uint8_t end_mark_size = sizeof(end_mark);
|
||||
|
||||
uint16_t size = lv_style_get_mem_size(style);
|
||||
uint16_t size = _lv_style_get_mem_size(style);
|
||||
if(size == 0) size += end_mark_size;
|
||||
|
||||
size += sizeof(lv_style_property_t) + sizeof(lv_opa_t);
|
||||
style->map = lv_mem_realloc(style->map, size);
|
||||
style_resize(style, size);
|
||||
LV_ASSERT_MEM(style->map);
|
||||
if(style == NULL) return;
|
||||
|
||||
lv_memcpy_small(style->map + size - new_prop_size - end_mark_size, &prop, sizeof(lv_style_property_t));
|
||||
lv_memcpy_small(style->map + size - sizeof(lv_opa_t) - end_mark_size, &opa, sizeof(lv_opa_t));
|
||||
lv_memcpy_small(style->map + size - end_mark_size, &end_mark, sizeof(end_mark));
|
||||
_lv_memcpy_small(style->map + size - new_prop_size - end_mark_size, &prop, sizeof(lv_style_property_t));
|
||||
_lv_memcpy_small(style->map + size - sizeof(lv_opa_t) - end_mark_size, &opa, sizeof(lv_opa_t));
|
||||
_lv_memcpy_small(style->map + size - end_mark_size, &end_mark, sizeof(end_mark));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -509,31 +507,31 @@ void _lv_style_set_ptr(lv_style_t * style, lv_style_property_t prop, const void
|
||||
lv_style_attr_t attr_found;
|
||||
lv_style_attr_t attr_goal;
|
||||
|
||||
attr_found.full = *(style->map + id + 1);
|
||||
attr_goal.full = (prop >> 8) & 0xFFU;
|
||||
attr_found = get_style_prop_attr(style, id);
|
||||
attr_goal = (prop >> 8) & 0xFFU;
|
||||
|
||||
if(attr_found.bits.state == attr_goal.bits.state) {
|
||||
lv_memcpy_small(style->map + id + sizeof(lv_style_property_t), &p, sizeof(const void * ));
|
||||
if(LV_STYLE_ATTR_GET_STATE(attr_found) == LV_STYLE_ATTR_GET_STATE(attr_goal)) {
|
||||
_lv_memcpy_small(style->map + id + sizeof(lv_style_property_t), &p, sizeof(const void *));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*Add new property if not exists yet*/
|
||||
uint8_t new_prop_size = (sizeof(lv_style_property_t) + sizeof(const void * ));
|
||||
uint8_t new_prop_size = (sizeof(lv_style_property_t) + sizeof(const void *));
|
||||
lv_style_property_t end_mark = _LV_STYLE_CLOSEING_PROP;
|
||||
uint8_t end_mark_size = sizeof(end_mark);
|
||||
|
||||
uint16_t size = lv_style_get_mem_size(style);
|
||||
uint16_t size = _lv_style_get_mem_size(style);
|
||||
if(size == 0) size += end_mark_size;
|
||||
|
||||
size += sizeof(lv_style_property_t) + sizeof(const void * );
|
||||
style->map = lv_mem_realloc(style->map, size);
|
||||
size += sizeof(lv_style_property_t) + sizeof(const void *);
|
||||
style_resize(style, size);
|
||||
LV_ASSERT_MEM(style->map);
|
||||
if(style == NULL) return;
|
||||
|
||||
lv_memcpy_small(style->map + size - new_prop_size - end_mark_size, &prop, sizeof(lv_style_property_t));
|
||||
lv_memcpy_small(style->map + size - sizeof(const void * ) - end_mark_size, &p, sizeof(const void * ));
|
||||
lv_memcpy_small(style->map + size - end_mark_size, &end_mark, sizeof(end_mark));
|
||||
_lv_memcpy_small(style->map + size - new_prop_size - end_mark_size, &prop, sizeof(lv_style_property_t));
|
||||
_lv_memcpy_small(style->map + size - sizeof(const void *) - end_mark_size, &p, sizeof(const void *));
|
||||
_lv_memcpy_small(style->map + size - end_mark_size, &end_mark, sizeof(end_mark));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -559,14 +557,14 @@ int16_t _lv_style_get_int(const lv_style_t * style, lv_style_property_t prop, vo
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
lv_memcpy_small(res, &style->map[id + sizeof(lv_style_property_t)], sizeof(lv_style_int_t));
|
||||
_lv_memcpy_small(res, &style->map[id + sizeof(lv_style_property_t)], sizeof(lv_style_int_t));
|
||||
lv_style_attr_t attr_act;
|
||||
attr_act.full = style->map[id + 1];
|
||||
attr_act = get_style_prop_attr(style, id);
|
||||
|
||||
lv_style_attr_t attr_goal;
|
||||
attr_goal.full = (prop >> 8) & 0xFF;
|
||||
attr_goal = (prop >> 8) & 0xFF;
|
||||
|
||||
return attr_act.bits.state & attr_goal.bits.state;
|
||||
return LV_STYLE_ATTR_GET_STATE(attr_act) & LV_STYLE_ATTR_GET_STATE(attr_goal);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -596,14 +594,14 @@ int16_t _lv_style_get_opa(const lv_style_t * style, lv_style_property_t prop, vo
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
lv_memcpy_small(res, &style->map[id + sizeof(lv_style_property_t)], sizeof(lv_opa_t));
|
||||
_lv_memcpy_small(res, &style->map[id + sizeof(lv_style_property_t)], sizeof(lv_opa_t));
|
||||
lv_style_attr_t attr_act;
|
||||
attr_act.full = style->map[id + 1];
|
||||
attr_act = get_style_prop_attr(style, id);
|
||||
|
||||
lv_style_attr_t attr_goal;
|
||||
attr_goal.full = (prop >> 8) & 0xFF;
|
||||
attr_goal = (prop >> 8) & 0xFF;
|
||||
|
||||
return attr_act.bits.state & attr_goal.bits.state;
|
||||
return LV_STYLE_ATTR_GET_STATE(attr_act) & LV_STYLE_ATTR_GET_STATE(attr_goal);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -630,14 +628,14 @@ int16_t _lv_style_get_color(const lv_style_t * style, lv_style_property_t prop,
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
lv_memcpy_small(res, &style->map[id + sizeof(lv_style_property_t)], sizeof(lv_color_t));
|
||||
_lv_memcpy_small(res, &style->map[id + sizeof(lv_style_property_t)], sizeof(lv_color_t));
|
||||
lv_style_attr_t attr_act;
|
||||
attr_act.full = style->map[id + 1];
|
||||
attr_act = get_style_prop_attr(style, id);
|
||||
|
||||
lv_style_attr_t attr_goal;
|
||||
attr_goal.full = (prop >> 8) & 0xFF;
|
||||
attr_goal = (prop >> 8) & 0xFF;
|
||||
|
||||
return attr_act.bits.state & attr_goal.bits.state;
|
||||
return LV_STYLE_ATTR_GET_STATE(attr_act) & LV_STYLE_ATTR_GET_STATE(attr_goal);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -665,14 +663,14 @@ int16_t _lv_style_get_ptr(const lv_style_t * style, lv_style_property_t prop, vo
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
lv_memcpy_small(res, &style->map[id + sizeof(lv_style_property_t)], sizeof(const void *));
|
||||
_lv_memcpy_small(res, &style->map[id + sizeof(lv_style_property_t)], sizeof(const void *));
|
||||
lv_style_attr_t attr_act;
|
||||
attr_act.full = style->map[id + 1];
|
||||
attr_act = get_style_prop_attr(style, id);
|
||||
|
||||
lv_style_attr_t attr_goal;
|
||||
attr_goal.full = (prop >> 8) & 0xFF;
|
||||
attr_goal = (prop >> 8) & 0xFF;
|
||||
|
||||
return attr_act.bits.state & attr_goal.bits.state;
|
||||
return LV_STYLE_ATTR_GET_STATE(attr_act) & LV_STYLE_ATTR_GET_STATE(attr_goal);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -695,7 +693,7 @@ lv_style_t * lv_style_list_get_local_style(lv_style_list_t * list)
|
||||
* @param list pointer to a style list where the local property should be set
|
||||
* @return pointer to the transition style if exists else `NULL`.
|
||||
*/
|
||||
lv_style_t * lv_style_list_get_transition_style(lv_style_list_t * list)
|
||||
lv_style_t * _lv_style_list_get_transition_style(lv_style_list_t * list)
|
||||
{
|
||||
LV_ASSERT_STYLE_LIST(list);
|
||||
|
||||
@@ -708,10 +706,10 @@ lv_style_t * lv_style_list_get_transition_style(lv_style_list_t * list)
|
||||
* @param list pointer to a style list
|
||||
* @return the transition style of a style list
|
||||
*/
|
||||
lv_style_t * lv_style_list_add_trans_style(lv_style_list_t * list)
|
||||
lv_style_t * _lv_style_list_add_trans_style(lv_style_list_t * list)
|
||||
{
|
||||
LV_ASSERT_STYLE_LIST(list);
|
||||
if(list->has_trans) return lv_style_list_get_transition_style(list);
|
||||
if(list->has_trans) return _lv_style_list_get_transition_style(list);
|
||||
|
||||
lv_style_t * trans_style = lv_mem_alloc(sizeof(lv_style_t));
|
||||
LV_ASSERT_MEM(trans_style);
|
||||
@@ -722,7 +720,7 @@ lv_style_t * lv_style_list_add_trans_style(lv_style_list_t * list)
|
||||
|
||||
lv_style_init(trans_style);
|
||||
|
||||
lv_style_list_add_style(list, trans_style);
|
||||
_lv_style_list_add_style(list, trans_style);
|
||||
list->has_trans = 1;
|
||||
|
||||
/*If the list has local style trans was added after it. But trans should be the first so swap them*/
|
||||
@@ -743,7 +741,7 @@ lv_style_t * lv_style_list_add_trans_style(lv_style_list_t * list)
|
||||
* @param value the value to set
|
||||
* @note for performance reasons it's not checked if the property really has integer type
|
||||
*/
|
||||
void lv_style_list_set_local_int(lv_style_list_t * list, lv_style_property_t prop, lv_style_int_t value)
|
||||
void _lv_style_list_set_local_int(lv_style_list_t * list, lv_style_property_t prop, lv_style_int_t value)
|
||||
{
|
||||
LV_ASSERT_STYLE_LIST(list);
|
||||
|
||||
@@ -759,7 +757,7 @@ void lv_style_list_set_local_int(lv_style_list_t * list, lv_style_property_t pro
|
||||
* @param value the value to set
|
||||
* @note for performance reasons it's not checked if the property really has opacity type
|
||||
*/
|
||||
void lv_style_list_set_local_opa(lv_style_list_t * list, lv_style_property_t prop, lv_opa_t value)
|
||||
void _lv_style_list_set_local_opa(lv_style_list_t * list, lv_style_property_t prop, lv_opa_t value)
|
||||
{
|
||||
LV_ASSERT_STYLE_LIST(list);
|
||||
|
||||
@@ -775,7 +773,7 @@ void lv_style_list_set_local_opa(lv_style_list_t * list, lv_style_property_t pro
|
||||
* @param value the value to set
|
||||
* @note for performance reasons it's not checked if the property really has color type
|
||||
*/
|
||||
void lv_style_list_set_local_color(lv_style_list_t * list, lv_style_property_t prop, lv_color_t value)
|
||||
void _lv_style_list_set_local_color(lv_style_list_t * list, lv_style_property_t prop, lv_color_t value)
|
||||
{
|
||||
LV_ASSERT_STYLE_LIST(list);
|
||||
|
||||
@@ -791,7 +789,7 @@ void lv_style_list_set_local_color(lv_style_list_t * list, lv_style_property_t p
|
||||
* @param value the value to set
|
||||
* @note for performance reasons it's not checked if the property really has pointer type
|
||||
*/
|
||||
void lv_style_list_set_local_ptr(lv_style_list_t * list, lv_style_property_t prop, const void * value)
|
||||
void _lv_style_list_set_local_ptr(lv_style_list_t * list, lv_style_property_t prop, const void * value)
|
||||
{
|
||||
LV_ASSERT_STYLE_LIST(list);
|
||||
|
||||
@@ -812,7 +810,7 @@ void lv_style_list_set_local_ptr(lv_style_list_t * list, lv_style_property_t pro
|
||||
* LV_RES_INV: there was NO matching property in the list
|
||||
* @note for performance reasons it's not checked if the property really has integer type
|
||||
*/
|
||||
lv_res_t lv_style_list_get_int(lv_style_list_t * list, lv_style_property_t prop, lv_style_int_t * res)
|
||||
lv_res_t _lv_style_list_get_int(lv_style_list_t * list, lv_style_property_t prop, lv_style_int_t * res)
|
||||
{
|
||||
LV_ASSERT_STYLE_LIST(list);
|
||||
|
||||
@@ -820,8 +818,8 @@ lv_res_t lv_style_list_get_int(lv_style_list_t * list, lv_style_property_t prop,
|
||||
if(list->style_list == NULL) return LV_RES_INV;
|
||||
|
||||
lv_style_attr_t attr;
|
||||
attr.full = prop >> 8;
|
||||
int16_t weight_goal = attr.full;
|
||||
attr = prop >> 8;
|
||||
int16_t weight_goal = attr;
|
||||
|
||||
int16_t weight = -1;
|
||||
|
||||
@@ -864,7 +862,7 @@ lv_res_t lv_style_list_get_int(lv_style_list_t * list, lv_style_property_t prop,
|
||||
* LV_RES_INV: there was NO matching property in the list
|
||||
* @note for performance reasons it's not checked if the property really has color type
|
||||
*/
|
||||
lv_res_t lv_style_list_get_color(lv_style_list_t * list, lv_style_property_t prop, lv_color_t * res)
|
||||
lv_res_t _lv_style_list_get_color(lv_style_list_t * list, lv_style_property_t prop, lv_color_t * res)
|
||||
{
|
||||
LV_ASSERT_STYLE_LIST(list);
|
||||
|
||||
@@ -872,12 +870,13 @@ lv_res_t lv_style_list_get_color(lv_style_list_t * list, lv_style_property_t pro
|
||||
if(list->style_list == NULL) return LV_RES_INV;
|
||||
|
||||
lv_style_attr_t attr;
|
||||
attr.full = prop >> 8;
|
||||
int16_t weight_goal = attr.full;
|
||||
attr = prop >> 8;
|
||||
int16_t weight_goal = attr;
|
||||
|
||||
int16_t weight = -1;
|
||||
|
||||
lv_color_t value_act = { 0 };
|
||||
lv_color_t value_act;
|
||||
value_act.full = 0;
|
||||
|
||||
int16_t ci;
|
||||
for(ci = 0; ci < list->style_cnt; ci++) {
|
||||
@@ -914,7 +913,7 @@ lv_res_t lv_style_list_get_color(lv_style_list_t * list, lv_style_property_t pro
|
||||
* LV_RES_INV: there was NO matching property in the list
|
||||
* @note for performance reasons it's not checked if the property really has opacity type
|
||||
*/
|
||||
lv_res_t lv_style_list_get_opa(lv_style_list_t * list, lv_style_property_t prop, lv_opa_t * res)
|
||||
lv_res_t _lv_style_list_get_opa(lv_style_list_t * list, lv_style_property_t prop, lv_opa_t * res)
|
||||
{
|
||||
LV_ASSERT_STYLE_LIST(list);
|
||||
|
||||
@@ -922,8 +921,8 @@ lv_res_t lv_style_list_get_opa(lv_style_list_t * list, lv_style_property_t prop,
|
||||
if(list->style_list == NULL) return LV_RES_INV;
|
||||
|
||||
lv_style_attr_t attr;
|
||||
attr.full = prop >> 8;
|
||||
int16_t weight_goal = attr.full;
|
||||
attr = prop >> 8;
|
||||
int16_t weight_goal = attr;
|
||||
|
||||
int16_t weight = -1;
|
||||
|
||||
@@ -964,7 +963,7 @@ lv_res_t lv_style_list_get_opa(lv_style_list_t * list, lv_style_property_t prop,
|
||||
* LV_RES_INV: there was NO matching property in the list
|
||||
* @note for performance reasons it's not checked if the property really has pointer type
|
||||
*/
|
||||
lv_res_t lv_style_list_get_ptr(lv_style_list_t * list, lv_style_property_t prop, const void ** res)
|
||||
lv_res_t _lv_style_list_get_ptr(lv_style_list_t * list, lv_style_property_t prop, const void ** res)
|
||||
{
|
||||
LV_ASSERT_STYLE_LIST(list);
|
||||
|
||||
@@ -972,8 +971,8 @@ lv_res_t lv_style_list_get_ptr(lv_style_list_t * list, lv_style_property_t prop,
|
||||
if(list->style_list == NULL) return LV_RES_INV;
|
||||
|
||||
lv_style_attr_t attr;
|
||||
attr.full = prop >> 8;
|
||||
int16_t weight_goal = attr.full;
|
||||
attr = prop >> 8;
|
||||
int16_t weight_goal = attr;
|
||||
|
||||
int16_t weight = -1;
|
||||
|
||||
@@ -1003,6 +1002,44 @@ lv_res_t lv_style_list_get_ptr(lv_style_list_t * list, lv_style_property_t prop,
|
||||
else return LV_RES_INV;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a style is valid (initialized correctly)
|
||||
* @param style pointer to a style
|
||||
* @return true: valid
|
||||
*/
|
||||
bool lv_debug_check_style(const lv_style_t * style)
|
||||
{
|
||||
if(style == NULL) return true; /*NULL style is still valid*/
|
||||
|
||||
#if LV_USE_ASSERT_STYLE
|
||||
if(style->sentinel != LV_DEBUG_STYLE_SENTINEL_VALUE) {
|
||||
LV_LOG_WARN("Invalid style (local variable or not initialized?)");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a style list is valid (initialized correctly)
|
||||
* @param style pointer to a style
|
||||
* @return true: valid
|
||||
*/
|
||||
bool lv_debug_check_style_list(const lv_style_list_t * list)
|
||||
{
|
||||
if(list == NULL) return true; /*NULL list is still valid*/
|
||||
|
||||
#if LV_USE_ASSERT_STYLE
|
||||
if(list->sentinel != LV_DEBUG_STYLE_LIST_SENTINEL_VALUE) {
|
||||
LV_LOG_WARN("Invalid style (local variable or not initialized?)");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
@@ -1023,40 +1060,36 @@ LV_ATTRIBUTE_FAST_MEM static inline int32_t get_property_index(const lv_style_t
|
||||
|
||||
uint8_t id_to_find = prop & 0xFF;
|
||||
lv_style_attr_t attr;
|
||||
attr.full = (prop >> 8) & 0xFF;
|
||||
attr = (prop >> 8) & 0xFF;
|
||||
|
||||
int16_t weight = -1;
|
||||
int16_t id_guess = -1;
|
||||
|
||||
size_t i = 0;
|
||||
while(style->map[i] != _LV_STYLE_CLOSEING_PROP) {
|
||||
if(style->map[i] == id_to_find) {
|
||||
|
||||
uint8_t prop_id;
|
||||
while((prop_id = get_style_prop_id(style, i)) != _LV_STYLE_CLOSEING_PROP) {
|
||||
if(prop_id == id_to_find) {
|
||||
lv_style_attr_t attr_i;
|
||||
attr_i.full = style->map[i + 1];
|
||||
attr_i = get_style_prop_attr(style, i);
|
||||
|
||||
/*If the state perfectly matches return this property*/
|
||||
if(attr_i.bits.state == attr.bits.state) {
|
||||
if(LV_STYLE_ATTR_GET_STATE(attr_i) == LV_STYLE_ATTR_GET_STATE(attr)) {
|
||||
return i;
|
||||
}
|
||||
/* Be sure the property not specifies other state than the requested.
|
||||
* E.g. For HOVER+PRESS, HOVER only is OK, but HOVER+FOCUS not*/
|
||||
else if((attr_i.bits.state & (~attr.bits.state)) == 0) {
|
||||
else if((LV_STYLE_ATTR_GET_STATE(attr_i) & (~LV_STYLE_ATTR_GET_STATE(attr))) == 0) {
|
||||
/* Use this property if it describes better the requested state than the current candidate.
|
||||
* E.g. for HOVER+FOCUS+PRESS prefer HOVER+FOCUS over FOCUS*/
|
||||
if(attr_i.bits.state > weight) {
|
||||
weight = attr_i.bits.state;
|
||||
if(LV_STYLE_ATTR_GET_STATE(attr_i) > weight) {
|
||||
weight = LV_STYLE_ATTR_GET_STATE(attr_i);
|
||||
id_guess = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*Go to the next property*/
|
||||
if((style->map[i] & 0xF) < LV_STYLE_ID_COLOR) i += sizeof(lv_style_int_t);
|
||||
else if((style->map[i] & 0xF) < LV_STYLE_ID_OPA) i += sizeof(lv_color_t);
|
||||
else if((style->map[i] & 0xF) < LV_STYLE_ID_PTR) i += sizeof(lv_opa_t);
|
||||
else i += sizeof(const void *);
|
||||
|
||||
i += sizeof(lv_style_property_t);
|
||||
i = get_next_prop_index(prop_id, i);
|
||||
}
|
||||
|
||||
return id_guess;
|
||||
@@ -1071,7 +1104,7 @@ static lv_style_t * get_alloc_local_style(lv_style_list_t * list)
|
||||
{
|
||||
LV_ASSERT_STYLE_LIST(list);
|
||||
|
||||
if(list->has_local) return lv_style_list_get_style(list, 0);
|
||||
if(list->has_local) return lv_style_list_get_style(list, list->has_trans ? 1 : 0);
|
||||
|
||||
lv_style_t * local_style = lv_mem_alloc(sizeof(lv_style_t));
|
||||
LV_ASSERT_MEM(local_style);
|
||||
@@ -1081,9 +1114,85 @@ static lv_style_t * get_alloc_local_style(lv_style_list_t * list)
|
||||
}
|
||||
lv_style_init(local_style);
|
||||
|
||||
/*Add the local style to the furst place*/
|
||||
lv_style_list_add_style(list, local_style);
|
||||
/*Add the local style to the first place*/
|
||||
_lv_style_list_add_style(list, local_style);
|
||||
list->has_local = 1;
|
||||
|
||||
return local_style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resizes a style map. Useful entry point for debugging.
|
||||
* @param style pointer to the style to be resized.
|
||||
* @param size new size
|
||||
*/
|
||||
static inline void style_resize(lv_style_t * style, size_t sz)
|
||||
{
|
||||
style->map = lv_mem_realloc(style->map, sz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get style property in index.
|
||||
* @param style pointer to style.
|
||||
* @param idx index of the style in style->map
|
||||
* @return property in style->map + idx
|
||||
*/
|
||||
static inline lv_style_property_t get_style_prop(const lv_style_t * style, size_t idx)
|
||||
{
|
||||
lv_style_property_t prop;
|
||||
uint8_t * prop_p = (uint8_t *)∝
|
||||
prop_p[0] = style->map[idx];
|
||||
prop_p[1] = style->map[idx + 1];
|
||||
return prop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get style property id in index.
|
||||
* @param style pointer to style.
|
||||
* @param idx index of the style in style->map
|
||||
* @return id of property in style->map + idx
|
||||
*/
|
||||
static inline uint8_t get_style_prop_id(const lv_style_t * style, size_t idx)
|
||||
{
|
||||
return get_style_prop(style, idx) & 0xFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get style property attributes for index.
|
||||
* @param style pointer to style.
|
||||
* @param idx index of the style in style->map
|
||||
* @return attribute of property in style->map + idx
|
||||
*/
|
||||
static inline uint8_t get_style_prop_attr(const lv_style_t * style, size_t idx)
|
||||
{
|
||||
return ((get_style_prop(style, idx) >> 8) & 0xFFU);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get property size.
|
||||
* @param prop_id property id.
|
||||
* @param idx index of the style in style->map
|
||||
* @return attribute of property in style->map + idx
|
||||
*/
|
||||
static inline size_t get_prop_size(uint8_t prop_id)
|
||||
{
|
||||
prop_id &= 0xF;
|
||||
size_t size = sizeof(lv_style_property_t);
|
||||
if(prop_id < LV_STYLE_ID_COLOR) size += sizeof(lv_style_int_t);
|
||||
else if(prop_id < LV_STYLE_ID_OPA) size += sizeof(lv_color_t);
|
||||
else if(prop_id < LV_STYLE_ID_PTR) size += sizeof(lv_opa_t);
|
||||
else size += sizeof(const void *);
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get next property index, given current property and index.
|
||||
* @param prop_id property id.
|
||||
* @param idx index of the style in style->map
|
||||
* @return index of next property in style->map
|
||||
*/
|
||||
static inline size_t get_next_prop_index(uint8_t prop_id, size_t idx)
|
||||
{
|
||||
return idx + get_prop_size(prop_id);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ extern "C" {
|
||||
#include "../lv_misc/lv_area.h"
|
||||
#include "../lv_misc/lv_anim.h"
|
||||
#include "../lv_misc/lv_types.h"
|
||||
#include "../lv_misc/lv_debug.h"
|
||||
#include "../lv_draw/lv_draw_blend.h"
|
||||
|
||||
/*********************
|
||||
@@ -80,13 +81,10 @@ enum {
|
||||
|
||||
typedef uint8_t lv_text_decor_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t state : 7; /* To which state the property refers to*/
|
||||
uint8_t inherit : 1; /*1: The property can be inherited*/
|
||||
} bits;
|
||||
uint8_t full;
|
||||
} lv_style_attr_t;
|
||||
typedef uint8_t lv_style_attr_t;
|
||||
|
||||
#define LV_STYLE_ATTR_GET_INHERIT(f) ((f)&0x80)
|
||||
#define LV_STYLE_ATTR_GET_STATE(f) ((f)&0x7F)
|
||||
|
||||
#define LV_STYLE_ID_VALUE 0x0 /*max 9 pcs*/
|
||||
#define LV_STYLE_ID_COLOR 0x9 /*max 3 pcs*/
|
||||
@@ -101,7 +99,7 @@ enum {
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TRANSFORM_WIDTH, 0x0, LV_STYLE_ID_VALUE + 4, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TRANSFORM_HEIGHT, 0x0, LV_STYLE_ID_VALUE + 5, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TRANSFORM_ANGLE, 0x0, LV_STYLE_ID_VALUE + 6, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TRANSFORM_ZOOM, 0x0, LV_STYLE_ID_VALUE + 7, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TRANSFORM_ZOOM, 0x0, LV_STYLE_ID_VALUE + 7, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_OPA_SCALE, 0x0, LV_STYLE_ID_OPA + 0, LV_STYLE_ATTR_INHERIT),
|
||||
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_PAD_TOP, 0x1, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_NONE),
|
||||
@@ -136,8 +134,8 @@ enum {
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_OUTLINE_OPA, 0x4, LV_STYLE_ID_OPA + 0, LV_STYLE_ATTR_NONE),
|
||||
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_WIDTH, 0x5, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_OFS_X, 0x5, LV_STYLE_ID_VALUE + 1, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_OFS_Y, 0x5, LV_STYLE_ID_VALUE + 2, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_OFS_X, 0x5, LV_STYLE_ID_VALUE + 1, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_OFS_Y, 0x5, LV_STYLE_ID_VALUE + 2, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_SPREAD, 0x5, LV_STYLE_ID_VALUE + 3, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_BLEND_MODE, 0x5, LV_STYLE_ID_VALUE + 4, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_COLOR, 0x5, LV_STYLE_ID_COLOR + 0, LV_STYLE_ATTR_NONE),
|
||||
@@ -193,12 +191,12 @@ enum {
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TRANSITION_PROP_6, 0xB, LV_STYLE_ID_VALUE + 7, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TRANSITION_PATH, 0xB, LV_STYLE_ID_PTR + 0, LV_STYLE_ATTR_NONE),
|
||||
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCALE_WIDTH, 0xC, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCALE_WIDTH, 0xC, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCALE_BORDER_WIDTH, 0xC, LV_STYLE_ID_VALUE + 1, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCALE_END_BORDER_WIDTH, 0xC, LV_STYLE_ID_VALUE + 2, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCALE_END_LINE_WIDTH, 0xC, LV_STYLE_ID_VALUE + 3, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCALE_GRAD_COLOR, 0xC, LV_STYLE_ID_COLOR + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCALE_END_COLOR, 0xC, LV_STYLE_ID_COLOR + 1, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCALE_END_LINE_WIDTH, 0xC, LV_STYLE_ID_VALUE + 3, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCALE_GRAD_COLOR, 0xC, LV_STYLE_ID_COLOR + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCALE_END_COLOR, 0xC, LV_STYLE_ID_COLOR + 1, LV_STYLE_ATTR_NONE),
|
||||
};
|
||||
|
||||
typedef uint16_t lv_style_property_t;
|
||||
@@ -223,11 +221,37 @@ typedef struct {
|
||||
#if LV_USE_ASSERT_STYLE
|
||||
uint32_t sentinel;
|
||||
#endif
|
||||
uint8_t style_cnt;
|
||||
uint8_t has_local : 1;
|
||||
uint8_t has_trans : 1;
|
||||
uint8_t skip_trans : 1; /*1: Temporally skip the transition style if any*/
|
||||
uint8_t ignore_trans : 1; /*1: Mark that this style list shouldn't receive transitions at all*/
|
||||
uint32_t style_cnt : 6;
|
||||
uint32_t has_local : 1;
|
||||
uint32_t has_trans : 1;
|
||||
uint32_t skip_trans : 1; /*1: Temporally skip the transition style if any*/
|
||||
uint32_t ignore_trans : 1; /*1: Mark that this style list shouldn't receive transitions at all*/
|
||||
uint32_t valid_cache : 1; /*1: The cache is valid and can be used*/
|
||||
uint32_t ignore_cache : 1; /*1: Ignore cache while getting value of properties*/
|
||||
|
||||
uint32_t radius_zero : 1;
|
||||
uint32_t opa_scale_cover : 1;
|
||||
uint32_t clip_corner_off : 1;
|
||||
uint32_t transform_all_zero : 1;
|
||||
uint32_t pad_all_zero : 1;
|
||||
uint32_t blend_mode_all_normal : 1;
|
||||
uint32_t bg_opa_transp : 1;
|
||||
uint32_t bg_opa_cover : 1;
|
||||
uint32_t bg_grad_dir_none : 1;
|
||||
|
||||
uint32_t border_width_zero : 1;
|
||||
uint32_t border_side_full : 1;
|
||||
uint32_t border_post_off : 1;
|
||||
|
||||
uint32_t outline_width_zero : 1;
|
||||
uint32_t pattern_img_null : 1;
|
||||
uint32_t shadow_width_zero : 1;
|
||||
uint32_t value_txt_str : 1;
|
||||
uint32_t img_recolor_opa_transp : 1;
|
||||
|
||||
uint32_t text_space_zero : 1;
|
||||
uint32_t text_decor_none : 1;
|
||||
uint32_t text_font_normal : 1;
|
||||
} lv_style_list_t;
|
||||
|
||||
/**********************
|
||||
@@ -267,21 +291,21 @@ void lv_style_list_copy(lv_style_list_t * list_dest, const lv_style_list_t * lis
|
||||
* @param list pointer to a style list
|
||||
* @param style pointer to a style to add
|
||||
*/
|
||||
void lv_style_list_add_style(lv_style_list_t * list, lv_style_t * style);
|
||||
void _lv_style_list_add_style(lv_style_list_t * list, lv_style_t * style);
|
||||
|
||||
/**
|
||||
* Remove a style from a style list
|
||||
* @param style_list pointer to a style list
|
||||
* @param style pointer to a style to remove
|
||||
*/
|
||||
void lv_style_list_remove_style(lv_style_list_t * list, lv_style_t * style);
|
||||
void _lv_style_list_remove_style(lv_style_list_t * list, lv_style_t * style);
|
||||
|
||||
/**
|
||||
* Remove all styles added from style list, clear the local style, transition style and free all allocated memories.
|
||||
* Leave `ignore_trans` flag as it is.
|
||||
* @param list pointer to a style list.
|
||||
*/
|
||||
void lv_style_list_reset(lv_style_list_t * style_list);
|
||||
void _lv_style_list_reset(lv_style_list_t * style_list);
|
||||
|
||||
static inline lv_style_t * lv_style_list_get_style(lv_style_list_t * list, uint8_t id)
|
||||
{
|
||||
@@ -301,7 +325,7 @@ void lv_style_reset(lv_style_t * style);
|
||||
* @param style pointer to a style
|
||||
* @return size of the properties in bytes
|
||||
*/
|
||||
uint16_t lv_style_get_mem_size(const lv_style_t * style);
|
||||
uint16_t _lv_style_get_mem_size(const lv_style_t * style);
|
||||
|
||||
/**
|
||||
* Copy a style to an other
|
||||
@@ -367,8 +391,6 @@ void _lv_style_set_opa(lv_style_t * style, lv_style_property_t prop, lv_opa_t op
|
||||
*/
|
||||
void _lv_style_set_ptr(lv_style_t * style, lv_style_property_t prop, const void * p);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get an integer typed property from a style.
|
||||
* @param style pointer to a style from where the property should be get
|
||||
@@ -441,14 +463,14 @@ lv_style_t * lv_style_list_get_local_style(lv_style_list_t * list);
|
||||
* @param list pointer to a style list where the local property should be set
|
||||
* @return pointer to the transition style if exists else `NULL`.
|
||||
*/
|
||||
lv_style_t * lv_style_list_get_transition_style(lv_style_list_t * list);
|
||||
lv_style_t * _lv_style_list_get_transition_style(lv_style_list_t * list);
|
||||
|
||||
/**
|
||||
* Allocate the transition style in a style list. If already exists simply return it.
|
||||
* @param list pointer to a style list
|
||||
* @return the transition style of a style list
|
||||
*/
|
||||
lv_style_t * lv_style_list_add_trans_style(lv_style_list_t * list);
|
||||
lv_style_t * _lv_style_list_add_trans_style(lv_style_list_t * list);
|
||||
|
||||
/**
|
||||
* Set a local integer typed property in a style list.
|
||||
@@ -458,7 +480,7 @@ lv_style_t * lv_style_list_add_trans_style(lv_style_list_t * list);
|
||||
* @param value the value to set
|
||||
* @note for performance reasons it's not checked if the property really has integer type
|
||||
*/
|
||||
void lv_style_list_set_local_int(lv_style_list_t * list, lv_style_property_t prop, lv_style_int_t value);
|
||||
void _lv_style_list_set_local_int(lv_style_list_t * list, lv_style_property_t prop, lv_style_int_t value);
|
||||
|
||||
/**
|
||||
* Set a local color typed property in a style list.
|
||||
@@ -468,7 +490,7 @@ void lv_style_list_set_local_int(lv_style_list_t * list, lv_style_property_t pro
|
||||
* @param value the value to set
|
||||
* @note for performance reasons it's not checked if the property really has color type
|
||||
*/
|
||||
void lv_style_list_set_local_color(lv_style_list_t * list, lv_style_property_t prop, lv_color_t value);
|
||||
void _lv_style_list_set_local_color(lv_style_list_t * list, lv_style_property_t prop, lv_color_t value);
|
||||
|
||||
/**
|
||||
* Set a local opacity typed property in a style list.
|
||||
@@ -478,7 +500,7 @@ void lv_style_list_set_local_color(lv_style_list_t * list, lv_style_property_t p
|
||||
* @param value the value to set
|
||||
* @note for performance reasons it's not checked if the property really has opacity type
|
||||
*/
|
||||
void lv_style_list_set_local_opa(lv_style_list_t * list, lv_style_property_t prop, lv_opa_t value);
|
||||
void _lv_style_list_set_local_opa(lv_style_list_t * list, lv_style_property_t prop, lv_opa_t value);
|
||||
|
||||
/**
|
||||
* Set a local pointer typed property in a style list.
|
||||
@@ -488,7 +510,7 @@ void lv_style_list_set_local_opa(lv_style_list_t * list, lv_style_property_t pro
|
||||
* @param value the value to set
|
||||
* @note for performance reasons it's not checked if the property really has pointer type
|
||||
*/
|
||||
void lv_style_list_set_local_ptr(lv_style_list_t * list, lv_style_property_t prop, const void * value);
|
||||
void _lv_style_list_set_local_ptr(lv_style_list_t * list, lv_style_property_t prop, const void * value);
|
||||
|
||||
/**
|
||||
* Get an integer typed property from a style list.
|
||||
@@ -501,7 +523,7 @@ void lv_style_list_set_local_ptr(lv_style_list_t * list, lv_style_property_t pro
|
||||
* LV_RES_INV: there was NO matching property in the list
|
||||
* @note for performance reasons it's not checked if the property really has integer type
|
||||
*/
|
||||
lv_res_t lv_style_list_get_int(lv_style_list_t * list, lv_style_property_t prop, lv_style_int_t * res);
|
||||
lv_res_t _lv_style_list_get_int(lv_style_list_t * list, lv_style_property_t prop, lv_style_int_t * res);
|
||||
|
||||
/**
|
||||
* Get a color typed property from a style list.
|
||||
@@ -514,7 +536,7 @@ lv_res_t lv_style_list_get_int(lv_style_list_t * list, lv_style_property_t prop,
|
||||
* LV_RES_INV: there was NO matching property in the list
|
||||
* @note for performance reasons it's not checked if the property really has color type
|
||||
*/
|
||||
lv_res_t lv_style_list_get_color(lv_style_list_t * list, lv_style_property_t prop, lv_color_t * res);
|
||||
lv_res_t _lv_style_list_get_color(lv_style_list_t * list, lv_style_property_t prop, lv_color_t * res);
|
||||
|
||||
|
||||
/**
|
||||
@@ -528,7 +550,7 @@ lv_res_t lv_style_list_get_color(lv_style_list_t * list, lv_style_property_t pro
|
||||
* LV_RES_INV: there was NO matching property in the list
|
||||
* @note for performance reasons it's not checked if the property really has opacity type
|
||||
*/
|
||||
lv_res_t lv_style_list_get_opa(lv_style_list_t * list, lv_style_property_t prop, lv_opa_t * res);
|
||||
lv_res_t _lv_style_list_get_opa(lv_style_list_t * list, lv_style_property_t prop, lv_opa_t * res);
|
||||
|
||||
/**
|
||||
* Get a pointer typed property from a style list.
|
||||
@@ -541,8 +563,21 @@ lv_res_t lv_style_list_get_opa(lv_style_list_t * list, lv_style_property_t prop,
|
||||
* LV_RES_INV: there was NO matching property in the list
|
||||
* @note for performance reasons it's not checked if the property really has pointer type
|
||||
*/
|
||||
lv_res_t lv_style_list_get_ptr(lv_style_list_t * list, lv_style_property_t prop, const void ** res);
|
||||
lv_res_t _lv_style_list_get_ptr(lv_style_list_t * list, lv_style_property_t prop, const void ** res);
|
||||
|
||||
/**
|
||||
* Check whether a style is valid (initialized correctly)
|
||||
* @param style pointer to a style
|
||||
* @return true: valid
|
||||
*/
|
||||
bool lv_debug_check_style(const lv_style_t * style);
|
||||
|
||||
/**
|
||||
* Check whether a style list is valid (initialized correctly)
|
||||
* @param style pointer to a style
|
||||
* @return true: valid
|
||||
*/
|
||||
bool lv_debug_check_style_list(const lv_style_list_t * list);
|
||||
|
||||
/*************************
|
||||
* GLOBAL VARIABLES
|
||||
@@ -561,9 +596,37 @@ lv_res_t lv_style_list_get_ptr(lv_style_list_t * list, lv_style_property_t prop,
|
||||
* lv_style_init(&my_style);
|
||||
* lv_style_copy(&my_style, &style_to_copy);
|
||||
*/
|
||||
#define LV_STYLE_CREATE(name, copy_p) static lv_style_t name; lv_style_init(&name); lv_style_copy(&name, copy);
|
||||
#define LV_STYLE_CREATE(name, copy_p) static lv_style_t name; lv_style_init(&name); lv_style_copy(&name, copy_p);
|
||||
|
||||
|
||||
|
||||
#if LV_USE_DEBUG
|
||||
|
||||
# ifndef LV_DEBUG_IS_STYLE
|
||||
# define LV_DEBUG_IS_STYLE(style_p) (lv_debug_check_style(style_p))
|
||||
# endif
|
||||
|
||||
# ifndef LV_DEBUG_IS_STYLE_LIST
|
||||
# define LV_DEBUG_IS_STYLE_LIST(list_p) (lv_debug_check_style_list(list_p))
|
||||
# endif
|
||||
|
||||
# if LV_USE_ASSERT_STYLE
|
||||
# ifndef LV_ASSERT_STYLE
|
||||
# define LV_ASSERT_STYLE(style_p) LV_DEBUG_ASSERT(LV_DEBUG_IS_STYLE(style_p), "Invalid style", style_p);
|
||||
# endif
|
||||
# ifndef LV_ASSERT_STYLE_LIST
|
||||
# define LV_ASSERT_STYLE_LIST(list_p) LV_DEBUG_ASSERT(LV_DEBUG_IS_STYLE_LIST(list_p), "Invalid style list", list_p);
|
||||
# endif
|
||||
# else
|
||||
# define LV_ASSERT_STYLE(style_p) true
|
||||
# define LV_ASSERT_STYLE_LIST(list_p) true
|
||||
# endif
|
||||
|
||||
#else
|
||||
# define LV_ASSERT_STYLE(p) true
|
||||
# define LV_ASSERT_STYLE_LIST(p) true
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
@@ -65,23 +65,26 @@ static void get_rounded_area(int16_t angle, lv_coord_t radius, uint8_t tickness,
|
||||
* @param mask the arc will be drawn only in this mask
|
||||
* @param start_angle the start angle of the arc (0 deg on the bottom, 90 deg on the right)
|
||||
* @param end_angle the end angle of the arc
|
||||
* @param style style of the arc (`body.thickness`, `body.main_color`, `body.opa` is used)
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
* @param clip_area the arc will be drawn only in this area
|
||||
* @param dsc pointer to an initialized `lv_draw_line_dsc_t` variable
|
||||
*/
|
||||
void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, uint16_t start_angle, uint16_t end_angle,
|
||||
const lv_area_t * clip_area, lv_draw_line_dsc_t * dsc)
|
||||
const lv_area_t * clip_area, const lv_draw_line_dsc_t * dsc)
|
||||
{
|
||||
if(dsc->opa <= LV_OPA_MIN) return;
|
||||
if(dsc->width == 0) return;
|
||||
if(start_angle == end_angle) return;
|
||||
|
||||
lv_style_int_t width = dsc->width;
|
||||
if(width > radius) width = radius;
|
||||
|
||||
lv_draw_rect_dsc_t cir_dsc;
|
||||
lv_draw_rect_dsc_init(&cir_dsc);
|
||||
cir_dsc.radius = LV_RADIUS_CIRCLE;
|
||||
cir_dsc.bg_opa = LV_OPA_TRANSP;
|
||||
cir_dsc.border_opa = dsc->opa;
|
||||
cir_dsc.border_color = dsc->color;
|
||||
cir_dsc.border_width = dsc->width;
|
||||
cir_dsc.border_width = width;
|
||||
cir_dsc.border_blend_mode = dsc->blend_mode;
|
||||
|
||||
lv_area_t area;
|
||||
@@ -121,7 +124,7 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, uin
|
||||
q_dsc.end_angle = end_angle;
|
||||
q_dsc.start_quarter = (start_angle / 90) & 0x3;
|
||||
q_dsc.end_quarter = (end_angle / 90) & 0x3;
|
||||
q_dsc.width = dsc->width;
|
||||
q_dsc.width = width;
|
||||
q_dsc.draw_dsc = &cir_dsc;
|
||||
q_dsc.draw_area = &area;
|
||||
q_dsc.clip_area = clip_area;
|
||||
@@ -144,7 +147,7 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, uin
|
||||
|
||||
lv_area_t round_area;
|
||||
if(dsc->round_start) {
|
||||
get_rounded_area(start_angle, radius, dsc->width, &round_area);
|
||||
get_rounded_area(start_angle, radius, width, &round_area);
|
||||
round_area.x1 += center_x;
|
||||
round_area.x2 += center_x;
|
||||
round_area.y1 += center_y;
|
||||
@@ -154,7 +157,7 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, uin
|
||||
}
|
||||
|
||||
if(dsc->round_end) {
|
||||
get_rounded_area(end_angle, radius, dsc->width, &round_area);
|
||||
get_rounded_area(end_angle, radius, width, &round_area);
|
||||
round_area.x1 += center_x;
|
||||
round_area.x2 += center_x;
|
||||
round_area.y1 += center_y;
|
||||
@@ -175,13 +178,13 @@ static void draw_quarter_0(quarter_draw_dsc_t * q)
|
||||
|
||||
if(q->start_quarter == 0 && q->end_quarter == 0 && q->start_angle < q->end_angle) {
|
||||
/*Small arc here*/
|
||||
quarter_area.y1 = q->center_y + ((lv_trigo_sin(q->start_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.x2 = q->center_x + ((lv_trigo_sin(q->start_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.y1 = q->center_y + ((_lv_trigo_sin(q->start_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.x2 = q->center_x + ((_lv_trigo_sin(q->start_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
|
||||
quarter_area.y2 = q->center_y + ((lv_trigo_sin(q->end_angle) * q->radius) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.x1 = q->center_x + ((lv_trigo_sin(q->end_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.y2 = q->center_y + ((_lv_trigo_sin(q->end_angle) * q->radius) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.x1 = q->center_x + ((_lv_trigo_sin(q->end_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
|
||||
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
bool ok = _lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
|
||||
}
|
||||
else if(q->start_quarter == 0 || q->end_quarter == 0) {
|
||||
@@ -190,20 +193,20 @@ static void draw_quarter_0(quarter_draw_dsc_t * q)
|
||||
quarter_area.x1 = q->center_x;
|
||||
quarter_area.y2 = q->center_y + q->radius;
|
||||
|
||||
quarter_area.y1 = q->center_y + ((lv_trigo_sin(q->start_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.x2 = q->center_x + ((lv_trigo_sin(q->start_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.y1 = q->center_y + ((_lv_trigo_sin(q->start_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.x2 = q->center_x + ((_lv_trigo_sin(q->start_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
|
||||
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
bool ok = _lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
|
||||
}
|
||||
if(q->end_quarter == 0) {
|
||||
quarter_area.x2 = q->center_x + q->radius;
|
||||
quarter_area.y1 = q->center_y;
|
||||
|
||||
quarter_area.y2 = q->center_y + ((lv_trigo_sin(q->end_angle) * q->radius) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.x1 = q->center_x + ((lv_trigo_sin(q->end_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.y2 = q->center_y + ((_lv_trigo_sin(q->end_angle) * q->radius) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.x1 = q->center_x + ((_lv_trigo_sin(q->end_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
|
||||
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
bool ok = _lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
|
||||
}
|
||||
}
|
||||
@@ -217,7 +220,7 @@ static void draw_quarter_0(quarter_draw_dsc_t * q)
|
||||
quarter_area.x2 = q->center_x + q->radius;
|
||||
quarter_area.y2 = q->center_y + q->radius;
|
||||
|
||||
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
bool ok = _lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
|
||||
}
|
||||
}
|
||||
@@ -228,13 +231,13 @@ static void draw_quarter_1(quarter_draw_dsc_t * q)
|
||||
|
||||
if(q->start_quarter == 1 && q->end_quarter == 1 && q->start_angle < q->end_angle) {
|
||||
/*Small arc here*/
|
||||
quarter_area.y2 = q->center_y + ((lv_trigo_sin(q->start_angle) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.x2 = q->center_x + ((lv_trigo_sin(q->start_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.y2 = q->center_y + ((_lv_trigo_sin(q->start_angle) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.x2 = q->center_x + ((_lv_trigo_sin(q->start_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
|
||||
quarter_area.y1 = q->center_y + ((lv_trigo_sin(q->end_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.x1 = q->center_x + ((lv_trigo_sin(q->end_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.y1 = q->center_y + ((_lv_trigo_sin(q->end_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.x1 = q->center_x + ((_lv_trigo_sin(q->end_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
|
||||
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
bool ok = _lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
|
||||
}
|
||||
else if(q->start_quarter == 1 || q->end_quarter == 1) {
|
||||
@@ -243,20 +246,20 @@ static void draw_quarter_1(quarter_draw_dsc_t * q)
|
||||
quarter_area.x1 = q->center_x - q->radius;
|
||||
quarter_area.y1 = q->center_y;
|
||||
|
||||
quarter_area.y2 = q->center_y + ((lv_trigo_sin(q->start_angle) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.x2 = q->center_x + ((lv_trigo_sin(q->start_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.y2 = q->center_y + ((_lv_trigo_sin(q->start_angle) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.x2 = q->center_x + ((_lv_trigo_sin(q->start_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
|
||||
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
bool ok = _lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
|
||||
}
|
||||
if(q->end_quarter == 1) {
|
||||
quarter_area.x2 = q->center_x - 1;
|
||||
quarter_area.y2 = q->center_y + q->radius;
|
||||
|
||||
quarter_area.y1 = q->center_y + ((lv_trigo_sin(q->end_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.x1 = q->center_x + ((lv_trigo_sin(q->end_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.y1 = q->center_y + ((_lv_trigo_sin(q->end_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.x1 = q->center_x + ((_lv_trigo_sin(q->end_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
|
||||
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
bool ok = _lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
|
||||
}
|
||||
}
|
||||
@@ -270,7 +273,7 @@ static void draw_quarter_1(quarter_draw_dsc_t * q)
|
||||
quarter_area.x2 = q->center_x - 1;
|
||||
quarter_area.y2 = q->center_y + q->radius;
|
||||
|
||||
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
bool ok = _lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
|
||||
}
|
||||
}
|
||||
@@ -281,13 +284,13 @@ static void draw_quarter_2(quarter_draw_dsc_t * q)
|
||||
|
||||
if(q->start_quarter == 2 && q->end_quarter == 2 && q->start_angle < q->end_angle) {
|
||||
/*Small arc here*/
|
||||
quarter_area.x1 = q->center_x + ((lv_trigo_sin(q->start_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.y2 = q->center_y + ((lv_trigo_sin(q->start_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.x1 = q->center_x + ((_lv_trigo_sin(q->start_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.y2 = q->center_y + ((_lv_trigo_sin(q->start_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
|
||||
quarter_area.y1 = q->center_y + ((lv_trigo_sin(q->end_angle) * q->radius) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.x2 = q->center_x + ((lv_trigo_sin(q->end_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.y1 = q->center_y + ((_lv_trigo_sin(q->end_angle) * q->radius) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.x2 = q->center_x + ((_lv_trigo_sin(q->end_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
|
||||
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
bool ok = _lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
|
||||
}
|
||||
else if(q->start_quarter == 2 || q->end_quarter == 2) {
|
||||
@@ -296,20 +299,20 @@ static void draw_quarter_2(quarter_draw_dsc_t * q)
|
||||
quarter_area.x2 = q->center_x - 1;
|
||||
quarter_area.y1 = q->center_y - q->radius;
|
||||
|
||||
quarter_area.x1 = q->center_x + ((lv_trigo_sin(q->start_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.y2 = q->center_y + ((lv_trigo_sin(q->start_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.x1 = q->center_x + ((_lv_trigo_sin(q->start_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.y2 = q->center_y + ((_lv_trigo_sin(q->start_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
|
||||
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
bool ok = _lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
|
||||
}
|
||||
if(q->end_quarter == 2) {
|
||||
quarter_area.x1 = q->center_x - q->radius;
|
||||
quarter_area.y2 = q->center_y - 1;
|
||||
|
||||
quarter_area.x2 = q->center_x + ((lv_trigo_sin(q->end_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.y1 = q->center_y + ((lv_trigo_sin(q->end_angle) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.x2 = q->center_x + ((_lv_trigo_sin(q->end_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.y1 = q->center_y + ((_lv_trigo_sin(q->end_angle) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
|
||||
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
bool ok = _lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
|
||||
}
|
||||
}
|
||||
@@ -323,7 +326,7 @@ static void draw_quarter_2(quarter_draw_dsc_t * q)
|
||||
quarter_area.x2 = q->center_x - 1;
|
||||
quarter_area.y2 = q->center_y - 1;
|
||||
|
||||
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
bool ok = _lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
|
||||
}
|
||||
}
|
||||
@@ -335,13 +338,13 @@ static void draw_quarter_3(quarter_draw_dsc_t * q)
|
||||
|
||||
if(q->start_quarter == 3 && q->end_quarter == 3 && q->start_angle < q->end_angle) {
|
||||
/*Small arc here*/
|
||||
quarter_area.x1 = q->center_x + ((lv_trigo_sin(q->start_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.y1 = q->center_y + ((lv_trigo_sin(q->start_angle) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.x1 = q->center_x + ((_lv_trigo_sin(q->start_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.y1 = q->center_y + ((_lv_trigo_sin(q->start_angle) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
|
||||
quarter_area.x2 = q->center_x + ((lv_trigo_sin(q->end_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.y2 = q->center_y + ((lv_trigo_sin(q->end_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.x2 = q->center_x + ((_lv_trigo_sin(q->end_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.y2 = q->center_y + ((_lv_trigo_sin(q->end_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
|
||||
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
bool ok = _lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
|
||||
}
|
||||
else if(q->start_quarter == 3 || q->end_quarter == 3) {
|
||||
@@ -350,20 +353,20 @@ static void draw_quarter_3(quarter_draw_dsc_t * q)
|
||||
quarter_area.x2 = q->center_x + q->radius;
|
||||
quarter_area.y2 = q->center_y - 1;
|
||||
|
||||
quarter_area.x1 = q->center_x + ((lv_trigo_sin(q->start_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.y1 = q->center_y + ((lv_trigo_sin(q->start_angle) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.x1 = q->center_x + ((_lv_trigo_sin(q->start_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.y1 = q->center_y + ((_lv_trigo_sin(q->start_angle) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
|
||||
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
bool ok = _lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
|
||||
}
|
||||
if(q->end_quarter == 3) {
|
||||
quarter_area.x1 = q->center_x;
|
||||
quarter_area.y1 = q->center_y - q->radius;
|
||||
|
||||
quarter_area.x2 = q->center_x + ((lv_trigo_sin(q->end_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.y2 = q->center_y + ((lv_trigo_sin(q->end_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.x2 = q->center_x + ((_lv_trigo_sin(q->end_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT);
|
||||
quarter_area.y2 = q->center_y + ((_lv_trigo_sin(q->end_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
|
||||
|
||||
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
bool ok = _lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
|
||||
}
|
||||
}
|
||||
@@ -377,7 +380,7 @@ static void draw_quarter_3(quarter_draw_dsc_t * q)
|
||||
quarter_area.x2 = q->center_x + q->radius;
|
||||
quarter_area.y2 = q->center_y - 1;
|
||||
|
||||
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
bool ok = _lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
|
||||
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
|
||||
}
|
||||
}
|
||||
@@ -403,8 +406,8 @@ static void get_rounded_area(int16_t angle, lv_coord_t radius, uint8_t tickness,
|
||||
int32_t cir_x;
|
||||
int32_t cir_y;
|
||||
|
||||
cir_x = ((radius - rx_corr - thick_half) * lv_trigo_sin(90 - angle)) >> (LV_TRIGO_SHIFT - ps);
|
||||
cir_y = ((radius - ry_corr - thick_half) * lv_trigo_sin(angle)) >> (LV_TRIGO_SHIFT - ps);
|
||||
cir_x = ((radius - rx_corr - thick_half) * _lv_trigo_sin(90 - angle)) >> (LV_TRIGO_SHIFT - ps);
|
||||
cir_y = ((radius - ry_corr - thick_half) * _lv_trigo_sin(angle)) >> (LV_TRIGO_SHIFT - ps);
|
||||
|
||||
/* Actually the center of the pixel need to be calculated so apply 1/2 px offset*/
|
||||
if(cir_x > 0) {
|
||||
|
||||
@@ -35,11 +35,11 @@ extern "C" {
|
||||
* @param mask the arc will be drawn only in this mask
|
||||
* @param start_angle the start angle of the arc (0 deg on the bottom, 90 deg on the right)
|
||||
* @param end_angle the end angle of the arc
|
||||
* @param style style of the arc (`body.thickness`, `body.main_color`, `body.opa` is used)
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
* @param clip_area the arc will be drawn only in this area
|
||||
* @param dsc pointer to an initialized `lv_draw_line_dsc_t` variable
|
||||
*/
|
||||
void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, uint16_t start_angle, uint16_t end_angle,
|
||||
const lv_area_t * clip_area, lv_draw_line_dsc_t * dsc);
|
||||
const lv_area_t * clip_area, const lv_draw_line_dsc_t * dsc);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
||||
@@ -31,33 +31,43 @@ static void fill_set_px(const lv_area_t * disp_area, lv_color_t * disp_buf, con
|
||||
lv_color_t color, lv_opa_t opa,
|
||||
const lv_opa_t * mask, lv_draw_mask_res_t mask_res);
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM static void fill_normal(const lv_area_t * disp_area, lv_color_t * disp_buf, const lv_area_t * draw_area,
|
||||
lv_color_t color, lv_opa_t opa,
|
||||
const lv_opa_t * mask, lv_draw_mask_res_t mask_res);
|
||||
LV_ATTRIBUTE_FAST_MEM static void fill_normal(const lv_area_t * disp_area, lv_color_t * disp_buf,
|
||||
const lv_area_t * draw_area,
|
||||
lv_color_t color, lv_opa_t opa,
|
||||
const lv_opa_t * mask, lv_draw_mask_res_t mask_res);
|
||||
|
||||
#if LV_USE_BLEND_MODES
|
||||
static void fill_blended(const lv_area_t * disp_area, lv_color_t * disp_buf, const lv_area_t * draw_area,
|
||||
lv_color_t color, lv_opa_t opa,
|
||||
const lv_opa_t * mask, lv_draw_mask_res_t mask_res, lv_blend_mode_t mode);
|
||||
#endif
|
||||
|
||||
static void map_set_px(const lv_area_t * disp_area, lv_color_t * disp_buf, const lv_area_t * draw_area,
|
||||
const lv_area_t * map_area, const lv_color_t * map_buf, lv_opa_t opa,
|
||||
const lv_opa_t * mask, lv_draw_mask_res_t mask_res);
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM static void map_normal(const lv_area_t * disp_area, lv_color_t * disp_buf, const lv_area_t * draw_area,
|
||||
const lv_area_t * map_area, const lv_color_t * map_buf, lv_opa_t opa,
|
||||
const lv_opa_t * mask, lv_draw_mask_res_t mask_res);
|
||||
LV_ATTRIBUTE_FAST_MEM static void map_normal(const lv_area_t * disp_area, lv_color_t * disp_buf,
|
||||
const lv_area_t * draw_area,
|
||||
const lv_area_t * map_area, const lv_color_t * map_buf, lv_opa_t opa,
|
||||
const lv_opa_t * mask, lv_draw_mask_res_t mask_res);
|
||||
|
||||
#if LV_USE_BLEND_MODES
|
||||
static void map_blended(const lv_area_t * disp_area, lv_color_t * disp_buf, const lv_area_t * draw_area,
|
||||
const lv_area_t * map_area, const lv_color_t * map_buf, lv_opa_t opa,
|
||||
const lv_opa_t * mask, lv_draw_mask_res_t mask_res, lv_blend_mode_t mode);
|
||||
|
||||
static inline lv_color_t color_blend_true_color_additive(lv_color_t fg, lv_color_t bg, lv_opa_t opa);
|
||||
static inline lv_color_t color_blend_true_color_subtractive(lv_color_t fg, lv_color_t bg, lv_opa_t opa);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
#if LV_USE_GPU || LV_USE_GPU_STM32_DMA2D
|
||||
LV_ATTRIBUTE_DMA static lv_color_t blend_buf[LV_HOR_RES_MAX];
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
@@ -72,13 +82,13 @@ static inline lv_color_t color_blend_true_color_subtractive(lv_color_t fg, lv_co
|
||||
|
||||
|
||||
#define FILL_NORMAL_MASK_PX_SCR_TRANSP(out_x, color) \
|
||||
if(*mask_tmp_x) { \
|
||||
if(*mask_tmp_x == LV_OPA_COVER) disp_buf_tmp[out_x] = color; \
|
||||
else if(disp->driver.screen_transp) lv_color_mix_with_alpha(disp_buf_tmp[out_x], disp_buf_tmp[out_x].ch.alpha, \
|
||||
color, *mask_tmp_x, &disp_buf_tmp[out_x], &disp_buf_tmp[out_x].ch.alpha); \
|
||||
else disp_buf_tmp[out_x] = lv_color_mix(color, disp_buf_tmp[out_x], *mask_tmp_x); \
|
||||
} \
|
||||
mask_tmp_x++;
|
||||
if(*mask_tmp_x) { \
|
||||
if(*mask_tmp_x == LV_OPA_COVER) disp_buf_first[out_x] = color; \
|
||||
else if(disp->driver.screen_transp) lv_color_mix_with_alpha(disp_buf_first[out_x], disp_buf_first[out_x].ch.alpha, \
|
||||
color, *mask_tmp_x, &disp_buf_first[out_x], &disp_buf_first[out_x].ch.alpha); \
|
||||
else disp_buf_first[out_x] = lv_color_mix(color, disp_buf_first[out_x], *mask_tmp_x); \
|
||||
} \
|
||||
mask_tmp_x++;
|
||||
|
||||
|
||||
#define MAP_NORMAL_MASK_PX(x) \
|
||||
@@ -89,13 +99,13 @@ static inline lv_color_t color_blend_true_color_subtractive(lv_color_t fg, lv_co
|
||||
mask_tmp_x++;
|
||||
|
||||
#define MAP_NORMAL_MASK_PX_SCR_TRANSP(x) \
|
||||
if(*mask_tmp_x) { \
|
||||
if(*mask_tmp_x == LV_OPA_COVER) disp_buf_tmp[x] = map_buf_tmp[x]; \
|
||||
else if(disp->driver.screen_transp) lv_color_mix_with_alpha(disp_buf_tmp[x], disp_buf_tmp[x].ch.alpha, \
|
||||
map_buf_tmp[x], *mask_tmp_x, &disp_buf_tmp[x], &disp_buf_tmp[x].ch.alpha); \
|
||||
else disp_buf_tmp[x] = lv_color_mix(map_buf_tmp[x], disp_buf_tmp[x], *mask_tmp_x); \
|
||||
} \
|
||||
mask_tmp_x++;
|
||||
if(*mask_tmp_x) { \
|
||||
if(*mask_tmp_x == LV_OPA_COVER) disp_buf_first[x] = map_buf_first[x]; \
|
||||
else if(disp->driver.screen_transp) lv_color_mix_with_alpha(disp_buf_first[x], disp_buf_first[x].ch.alpha, \
|
||||
map_buf_first[x], *mask_tmp_x, &disp_buf_first[x], &disp_buf_first[x].ch.alpha); \
|
||||
else disp_buf_first[x] = lv_color_mix(map_buf_first[x], disp_buf_first[x], *mask_tmp_x); \
|
||||
} \
|
||||
mask_tmp_x++;
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
@@ -115,17 +125,15 @@ mask_tmp_x++;
|
||||
* @param opa overall opacity in 0x00..0xff range
|
||||
* @param mode blend mode from `lv_blend_mode_t`
|
||||
*/
|
||||
LV_ATTRIBUTE_FAST_MEM void lv_blend_fill(const lv_area_t * clip_area, const lv_area_t * fill_area,
|
||||
lv_color_t color, lv_opa_t * mask, lv_draw_mask_res_t mask_res, lv_opa_t opa,
|
||||
lv_blend_mode_t mode)
|
||||
LV_ATTRIBUTE_FAST_MEM void _lv_blend_fill(const lv_area_t * clip_area, const lv_area_t * fill_area,
|
||||
lv_color_t color, lv_opa_t * mask, lv_draw_mask_res_t mask_res, lv_opa_t opa,
|
||||
lv_blend_mode_t mode)
|
||||
{
|
||||
static int asd = 0;
|
||||
asd++;
|
||||
/*Do not draw transparent things*/
|
||||
if(opa < LV_OPA_MIN) return;
|
||||
if(mask_res == LV_DRAW_MASK_RES_TRANSP) return;
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
const lv_area_t * disp_area = &vdb->area;
|
||||
lv_color_t * disp_buf = vdb->buf_act;
|
||||
@@ -135,7 +143,7 @@ LV_ATTRIBUTE_FAST_MEM void lv_blend_fill(const lv_area_t * clip_area, const lv_a
|
||||
* It is always the same or inside `fill_area` */
|
||||
lv_area_t draw_area;
|
||||
bool is_common;
|
||||
is_common = lv_area_intersect(&draw_area, clip_area, fill_area);
|
||||
is_common = _lv_area_intersect(&draw_area, clip_area, fill_area);
|
||||
if(!is_common) return;
|
||||
|
||||
/* Now `draw_area` has absolute coordinates.
|
||||
@@ -163,9 +171,11 @@ LV_ATTRIBUTE_FAST_MEM void lv_blend_fill(const lv_area_t * clip_area, const lv_a
|
||||
else if(mode == LV_BLEND_MODE_NORMAL) {
|
||||
fill_normal(disp_area, disp_buf, &draw_area, color, opa, mask, mask_res);
|
||||
}
|
||||
#if LV_USE_BLEND_MODES
|
||||
else {
|
||||
fill_blended(disp_area, disp_buf, &draw_area, color, opa, mask, mask_res, mode);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -181,9 +191,10 @@ LV_ATTRIBUTE_FAST_MEM void lv_blend_fill(const lv_area_t * clip_area, const lv_a
|
||||
* @param opa overall opacity in 0x00..0xff range
|
||||
* @param mode blend mode from `lv_blend_mode_t`
|
||||
*/
|
||||
LV_ATTRIBUTE_FAST_MEM void lv_blend_map(const lv_area_t * clip_area, const lv_area_t * map_area, const lv_color_t * map_buf,
|
||||
lv_opa_t * mask, lv_draw_mask_res_t mask_res,
|
||||
lv_opa_t opa, lv_blend_mode_t mode)
|
||||
LV_ATTRIBUTE_FAST_MEM void _lv_blend_map(const lv_area_t * clip_area, const lv_area_t * map_area,
|
||||
const lv_color_t * map_buf,
|
||||
lv_opa_t * mask, lv_draw_mask_res_t mask_res,
|
||||
lv_opa_t opa, lv_blend_mode_t mode)
|
||||
{
|
||||
/*Do not draw transparent things*/
|
||||
if(opa < LV_OPA_MIN) return;
|
||||
@@ -193,10 +204,10 @@ LV_ATTRIBUTE_FAST_MEM void lv_blend_map(const lv_area_t * clip_area, const lv_ar
|
||||
* It is always the same or inside `fill_area` */
|
||||
lv_area_t draw_area;
|
||||
bool is_common;
|
||||
is_common = lv_area_intersect(&draw_area, clip_area, map_area);
|
||||
is_common = _lv_area_intersect(&draw_area, clip_area, map_area);
|
||||
if(!is_common) return;
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
const lv_area_t * disp_area = &vdb->area;
|
||||
lv_color_t * disp_buf = vdb->buf_act;
|
||||
@@ -225,9 +236,11 @@ LV_ATTRIBUTE_FAST_MEM void lv_blend_map(const lv_area_t * clip_area, const lv_ar
|
||||
else if(mode == LV_BLEND_MODE_NORMAL) {
|
||||
map_normal(disp_area, disp_buf, &draw_area, map_area, map_buf, opa, mask, mask_res);
|
||||
}
|
||||
#if LV_USE_BLEND_MODES
|
||||
else {
|
||||
map_blended(disp_area, disp_buf, &draw_area, map_area, map_buf, opa, mask, mask_res, mode);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -240,7 +253,7 @@ static void fill_set_px(const lv_area_t * disp_area, lv_color_t * disp_buf, con
|
||||
const lv_opa_t * mask, lv_draw_mask_res_t mask_res)
|
||||
{
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
|
||||
/*Get the width of the `disp_area` it will be used to go to the next line*/
|
||||
int32_t disp_w = lv_area_get_width(disp_area);
|
||||
@@ -266,8 +279,10 @@ static void fill_set_px(const lv_area_t * disp_area, lv_color_t * disp_buf, con
|
||||
|
||||
for(y = draw_area->y1; y <= draw_area->y2; y++) {
|
||||
for(x = draw_area->x1; x <= draw_area->x2; x++) {
|
||||
disp->driver.set_px_cb(&disp->driver, (void *)disp_buf, disp_w, x, y, color,
|
||||
(uint32_t)((uint32_t)opa * mask_tmp[x]) >> 8);
|
||||
if(mask_tmp[x]) {
|
||||
disp->driver.set_px_cb(&disp->driver, (void *)disp_buf, disp_w, x, y, color,
|
||||
(uint32_t)((uint32_t)opa * mask_tmp[x]) >> 8);
|
||||
}
|
||||
}
|
||||
mask_tmp += draw_area_w;
|
||||
}
|
||||
@@ -287,13 +302,14 @@ static void fill_set_px(const lv_area_t * disp_area, lv_color_t * disp_buf, con
|
||||
* LV_MASK_RES_TRANSP: the mask has only 0x00 values (full transparent),
|
||||
* LV_MASK_RES_CHANGED: the mask has mixed values
|
||||
*/
|
||||
LV_ATTRIBUTE_FAST_MEM static void fill_normal(const lv_area_t * disp_area, lv_color_t * disp_buf, const lv_area_t * draw_area,
|
||||
lv_color_t color, lv_opa_t opa,
|
||||
const lv_opa_t * mask, lv_draw_mask_res_t mask_res)
|
||||
LV_ATTRIBUTE_FAST_MEM static void fill_normal(const lv_area_t * disp_area, lv_color_t * disp_buf,
|
||||
const lv_area_t * draw_area,
|
||||
lv_color_t color, lv_opa_t opa,
|
||||
const lv_opa_t * mask, lv_draw_mask_res_t mask_res)
|
||||
{
|
||||
|
||||
#if LV_USE_GPU
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
#if LV_USE_GPU || LV_COLOR_SCREEN_TRANSP
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
#endif
|
||||
|
||||
/*Get the width of the `disp_area` it will be used to go to the next line*/
|
||||
@@ -316,12 +332,13 @@ LV_ATTRIBUTE_FAST_MEM static void fill_normal(const lv_area_t * disp_area, lv_co
|
||||
disp->driver.gpu_fill_cb(&disp->driver, disp_buf, disp_w, draw_area, color);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LV_USE_GPU_STM32_DMA2D
|
||||
if(lv_area_get_size(draw_area) >= 240) {
|
||||
lv_gpu_stm32_dma2d_fill(disp_buf_first, disp_w, color, draw_area_w, draw_area_h);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
/*Software rendering*/
|
||||
for(y = 0; y < draw_area_h; y++) {
|
||||
@@ -333,7 +350,6 @@ LV_ATTRIBUTE_FAST_MEM static void fill_normal(const lv_area_t * disp_area, lv_co
|
||||
else {
|
||||
#if LV_USE_GPU
|
||||
if(disp->driver.gpu_blend_cb && lv_area_get_size(draw_area) > GPU_SIZE_LIMIT) {
|
||||
static lv_color_t blend_buf[LV_HOR_RES_MAX];
|
||||
for(x = 0; x < draw_area_w ; x++) blend_buf[x].full = color.full;
|
||||
|
||||
for(y = draw_area->y1; y <= draw_area->y2; y++) {
|
||||
@@ -343,6 +359,25 @@ LV_ATTRIBUTE_FAST_MEM static void fill_normal(const lv_area_t * disp_area, lv_co
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if LV_USE_GPU_STM32_DMA2D
|
||||
if(lv_area_get_size(draw_area) >= 240) {
|
||||
if(blend_buf[0].full != color.full) lv_color_fill(blend_buf, color, LV_HOR_RES_MAX);
|
||||
|
||||
lv_coord_t line_h = LV_HOR_RES_MAX / draw_area_w;
|
||||
for(y = 0; y <= draw_area_h - line_h; y += line_h) {
|
||||
lv_gpu_stm32_dma2d_blend(disp_buf_first, disp_w, blend_buf, opa, draw_area_w, draw_area_w, line_h);
|
||||
disp_buf_first += disp_w * line_h;
|
||||
}
|
||||
|
||||
if(y != draw_area_h) {
|
||||
lv_gpu_stm32_dma2d_blend(disp_buf_first, disp_w, blend_buf, opa, draw_area_w, draw_area_w, draw_area_h - y);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
lv_color_t last_dest_color = LV_COLOR_BLACK;
|
||||
lv_color_t last_res_color = lv_color_mix(color, last_dest_color, opa);
|
||||
|
||||
@@ -397,7 +432,7 @@ LV_ATTRIBUTE_FAST_MEM static void fill_normal(const lv_area_t * disp_area, lv_co
|
||||
for(y = 0; y < draw_area_h; y++) {
|
||||
const lv_opa_t * mask_tmp_x = mask;
|
||||
#if 0
|
||||
for(x = draw_area->x1; x <= draw_area->x2; x++) {
|
||||
for(x = 0; x < draw_area_w; x++) {
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
FILL_NORMAL_MASK_PX_SCR_TRANSP(x, color)
|
||||
#else
|
||||
@@ -460,8 +495,8 @@ LV_ATTRIBUTE_FAST_MEM static void fill_normal(const lv_area_t * disp_area, lv_co
|
||||
const lv_opa_t * mask_tmp_x = mask;
|
||||
for(x = 0; x < draw_area_w; x++) {
|
||||
if(*mask_tmp_x) {
|
||||
if(*mask_tmp_x != last_mask) opa_tmp = *mask_tmp_x == LV_OPA_COVER ? opa : (uint32_t)((uint32_t)(
|
||||
*mask_tmp_x) * opa) >> 8;
|
||||
if(*mask_tmp_x != last_mask) opa_tmp = *mask_tmp_x == LV_OPA_COVER ? opa :
|
||||
(uint32_t)((uint32_t)(*mask_tmp_x) * opa) >> 8;
|
||||
if(*mask_tmp_x != last_mask || last_dest_color.full != disp_buf_first[x].full) {
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
if(disp->driver.screen_transp) {
|
||||
@@ -488,7 +523,7 @@ LV_ATTRIBUTE_FAST_MEM static void fill_normal(const lv_area_t * disp_area, lv_co
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if LV_USE_BLEND_MODES
|
||||
/**
|
||||
* Fill an area with a color but apply blending algorithms
|
||||
* @param disp_area the current display area (destination area)
|
||||
@@ -579,13 +614,14 @@ static void fill_blended(const lv_area_t * disp_area, lv_color_t * disp_buf, co
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void map_set_px(const lv_area_t * disp_area, lv_color_t * disp_buf, const lv_area_t * draw_area,
|
||||
const lv_area_t * map_area, const lv_color_t * map_buf, lv_opa_t opa,
|
||||
const lv_opa_t * mask, lv_draw_mask_res_t mask_res)
|
||||
|
||||
{
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
|
||||
/*Get the width of the `disp_area` it will be used to go to the next line*/
|
||||
int32_t disp_w = lv_area_get_width(disp_area);
|
||||
@@ -620,8 +656,10 @@ static void map_set_px(const lv_area_t * disp_area, lv_color_t * disp_buf, cons
|
||||
|
||||
for(y = draw_area->y1; y <= draw_area->y2; y++) {
|
||||
for(x = draw_area->x1; x <= draw_area->x2; x++) {
|
||||
disp->driver.set_px_cb(&disp->driver, (void *)disp_buf, disp_w, x, y, map_buf_tmp[x],
|
||||
(uint32_t)((uint32_t)opa * mask_tmp[x]) >> 8);
|
||||
if(mask_tmp[x]) {
|
||||
disp->driver.set_px_cb(&disp->driver, (void *)disp_buf, disp_w, x, y, map_buf_tmp[x],
|
||||
(uint32_t)((uint32_t)opa * mask_tmp[x]) >> 8);
|
||||
}
|
||||
}
|
||||
mask_tmp += draw_area_w;
|
||||
map_buf_tmp += map_w;
|
||||
@@ -642,9 +680,10 @@ static void map_set_px(const lv_area_t * disp_area, lv_color_t * disp_buf, cons
|
||||
* LV_MASK_RES_TRANSP: the mask has only 0x00 values (full transparent),
|
||||
* LV_MASK_RES_CHANGED: the mask has mixed values
|
||||
*/
|
||||
LV_ATTRIBUTE_FAST_MEM static void map_normal(const lv_area_t * disp_area, lv_color_t * disp_buf, const lv_area_t * draw_area,
|
||||
const lv_area_t * map_area, const lv_color_t * map_buf, lv_opa_t opa,
|
||||
const lv_opa_t * mask, lv_draw_mask_res_t mask_res)
|
||||
LV_ATTRIBUTE_FAST_MEM static void map_normal(const lv_area_t * disp_area, lv_color_t * disp_buf,
|
||||
const lv_area_t * draw_area,
|
||||
const lv_area_t * map_area, const lv_color_t * map_buf, lv_opa_t opa,
|
||||
const lv_opa_t * mask, lv_draw_mask_res_t mask_res)
|
||||
{
|
||||
|
||||
/*Get the width of the `disp_area` it will be used to go to the next line*/
|
||||
@@ -663,11 +702,8 @@ LV_ATTRIBUTE_FAST_MEM static void map_normal(const lv_area_t * disp_area, lv_col
|
||||
const lv_color_t * map_buf_first = map_buf + map_w * (draw_area->y1 - (map_area->y1 - disp_area->y1));
|
||||
map_buf_first += (draw_area->x1 - (map_area->x1 - disp_area->x1));
|
||||
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
lv_opa_t opa_composed;
|
||||
#endif
|
||||
#if LV_COLOR_SCREEN_TRANSP || LV_USE_GPU
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
#endif
|
||||
|
||||
int32_t x;
|
||||
@@ -688,28 +724,28 @@ LV_ATTRIBUTE_FAST_MEM static void map_normal(const lv_area_t * disp_area, lv_col
|
||||
|
||||
if(opa > LV_OPA_MAX) {
|
||||
#if LV_USE_GPU_STM32_DMA2D
|
||||
if(lv_area_get_size(draw_area) >= 240) {
|
||||
lv_gpu_stm32_dma2d_copy(disp_buf_first, disp_w, map_buf_first, map_w, draw_area_w, draw_area_h);
|
||||
return;
|
||||
}
|
||||
if(lv_area_get_size(draw_area) >= 240) {
|
||||
lv_gpu_stm32_dma2d_copy(disp_buf_first, disp_w, map_buf_first, map_w, draw_area_w, draw_area_h);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*Software rendering*/
|
||||
for(y = 0; y < draw_area_h; y++) {
|
||||
lv_memcpy(disp_buf_first, map_buf_first, draw_area_w * sizeof(lv_color_t));
|
||||
_lv_memcpy(disp_buf_first, map_buf_first, draw_area_w * sizeof(lv_color_t));
|
||||
disp_buf_first += disp_w;
|
||||
map_buf_first += map_w;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#if LV_USE_GPU_STM32_DMA2D
|
||||
if(lv_area_get_size(draw_area) >= 240) {
|
||||
lv_gpu_stm32_dma2d_blend(disp_buf_first, disp_w, map_buf_first, opa, map_w, draw_area_w, draw_area_h);
|
||||
return;
|
||||
}
|
||||
if(lv_area_get_size(draw_area) >= 240) {
|
||||
lv_gpu_stm32_dma2d_blend(disp_buf_first, disp_w, map_buf_first, opa, map_w, draw_area_w, draw_area_h);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*Software rendering*/
|
||||
/*Software rendering*/
|
||||
|
||||
for(y = 0; y < draw_area_h; y++) {
|
||||
for(x = 0; x < draw_area_w; x++) {
|
||||
@@ -740,15 +776,15 @@ LV_ATTRIBUTE_FAST_MEM static void map_normal(const lv_area_t * disp_area, lv_col
|
||||
for(y = 0; y < draw_area_h; y++) {
|
||||
const lv_opa_t * mask_tmp_x = mask;
|
||||
#if 0
|
||||
for(x = draw_area->x1; x <= draw_area->x2; x++) {
|
||||
for(x = 0; x < draw_area_w; x++) {
|
||||
MAP_NORMAL_MASK_PX(x);
|
||||
}
|
||||
#else
|
||||
for(x = 0; x < draw_area_w && ((lv_uintptr_t)mask_tmp_x & 0x3); x++) {
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
MAP_NORMAL_MASK_PX_SCR_TRANSP(x)
|
||||
MAP_NORMAL_MASK_PX_SCR_TRANSP(x)
|
||||
#else
|
||||
MAP_NORMAL_MASK_PX(x)
|
||||
MAP_NORMAL_MASK_PX(x)
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -818,7 +854,7 @@ LV_ATTRIBUTE_FAST_MEM static void map_normal(const lv_area_t * disp_area, lv_col
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_USE_BLEND_MODES
|
||||
static void map_blended(const lv_area_t * disp_area, lv_color_t * disp_buf, const lv_area_t * draw_area,
|
||||
const lv_area_t * map_area, const lv_color_t * map_buf, lv_opa_t opa,
|
||||
const lv_opa_t * mask, lv_draw_mask_res_t mask_res, lv_blend_mode_t mode)
|
||||
@@ -969,3 +1005,4 @@ static inline lv_color_t color_blend_true_color_subtractive(lv_color_t fg, lv_co
|
||||
|
||||
return lv_color_mix(fg, bg, opa);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -26,8 +26,10 @@ extern "C" {
|
||||
**********************/
|
||||
enum {
|
||||
LV_BLEND_MODE_NORMAL,
|
||||
#if LV_USE_BLEND_MODES
|
||||
LV_BLEND_MODE_ADDITIVE,
|
||||
LV_BLEND_MODE_SUBTRACTIVE,
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef uint8_t lv_blend_mode_t;
|
||||
@@ -36,13 +38,16 @@ typedef uint8_t lv_blend_mode_t;
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM void lv_blend_fill(const lv_area_t * clip_area, const lv_area_t * fill_area, lv_color_t color,
|
||||
lv_opa_t * mask, lv_draw_mask_res_t mask_res, lv_opa_t opa, lv_blend_mode_t mode);
|
||||
//! @cond Doxygen_Suppress
|
||||
LV_ATTRIBUTE_FAST_MEM void _lv_blend_fill(const lv_area_t * clip_area, const lv_area_t * fill_area, lv_color_t color,
|
||||
lv_opa_t * mask, lv_draw_mask_res_t mask_res, lv_opa_t opa, lv_blend_mode_t mode);
|
||||
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM void lv_blend_map(const lv_area_t * clip_area, const lv_area_t * map_area, const lv_color_t * map_buf,
|
||||
lv_opa_t * mask, lv_draw_mask_res_t mask_res, lv_opa_t opa, lv_blend_mode_t mode);
|
||||
LV_ATTRIBUTE_FAST_MEM void _lv_blend_map(const lv_area_t * clip_area, const lv_area_t * map_area,
|
||||
const lv_color_t * map_buf,
|
||||
lv_opa_t * mask, lv_draw_mask_res_t mask_res, lv_opa_t opa, lv_blend_mode_t mode);
|
||||
|
||||
//! @endcond
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
@@ -27,12 +27,14 @@
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mask, const void * src,
|
||||
lv_draw_img_dsc_t * draw_dsc);
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * clip_area,
|
||||
const void * src,
|
||||
const lv_draw_img_dsc_t * draw_dsc);
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const lv_area_t * clip_area, const uint8_t * map_p,
|
||||
lv_draw_img_dsc_t * draw_dsc,
|
||||
bool chroma_key, bool alpha_byte);
|
||||
LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const lv_area_t * clip_area,
|
||||
const uint8_t * map_p,
|
||||
const lv_draw_img_dsc_t * draw_dsc,
|
||||
bool chroma_key, bool alpha_byte);
|
||||
|
||||
static void show_error(const lv_area_t * coords, const lv_area_t * clip_area, const char * msg);
|
||||
|
||||
@@ -50,7 +52,7 @@ static void show_error(const lv_area_t * coords, const lv_area_t * clip_area, co
|
||||
|
||||
void lv_draw_img_dsc_init(lv_draw_img_dsc_t * dsc)
|
||||
{
|
||||
lv_memset_00(dsc, sizeof(lv_draw_img_dsc_t));
|
||||
_lv_memset_00(dsc, sizeof(lv_draw_img_dsc_t));
|
||||
dsc->recolor = LV_COLOR_BLACK;
|
||||
dsc->opa = LV_OPA_COVER;
|
||||
dsc->zoom = LV_IMG_ZOOM_NONE;
|
||||
@@ -63,13 +65,9 @@ void lv_draw_img_dsc_init(lv_draw_img_dsc_t * dsc)
|
||||
* @param coords the coordinates of the image
|
||||
* @param mask the image will be drawn only in this area
|
||||
* @param src pointer to a lv_color_t array which contains the pixels of the image
|
||||
* @param style style of the image
|
||||
* @param angle rotation angle of the image
|
||||
* @param center rotation center of the image
|
||||
* @param antialias anti-alias transformations (rotate, zoom) or not
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
* @param dsc pointer to an initialized `lv_draw_img_dsc_t` variable
|
||||
*/
|
||||
void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * src, lv_draw_img_dsc_t * dsc)
|
||||
void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * src, const lv_draw_img_dsc_t * dsc)
|
||||
{
|
||||
if(src == NULL) {
|
||||
LV_LOG_WARN("Image draw: src is NULL");
|
||||
@@ -146,12 +144,10 @@ bool lv_img_cf_is_chroma_keyed(lv_img_cf_t cf)
|
||||
switch(cf) {
|
||||
case LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED:
|
||||
case LV_IMG_CF_RAW_CHROMA_KEYED:
|
||||
#if LV_INDEXED_CHROMA
|
||||
case LV_IMG_CF_INDEXED_1BIT:
|
||||
case LV_IMG_CF_INDEXED_2BIT:
|
||||
case LV_IMG_CF_INDEXED_4BIT:
|
||||
case LV_IMG_CF_INDEXED_8BIT:
|
||||
#endif
|
||||
is_chroma_keyed = true;
|
||||
break;
|
||||
|
||||
@@ -230,12 +226,13 @@ lv_img_src_t lv_img_src_get_type(const void * src)
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mask, const void * src,
|
||||
lv_draw_img_dsc_t * draw_dsc)
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * clip_area,
|
||||
const void * src,
|
||||
const lv_draw_img_dsc_t * draw_dsc)
|
||||
{
|
||||
if(draw_dsc->opa <= LV_OPA_MIN) return LV_RES_OK;
|
||||
|
||||
lv_img_cache_entry_t * cdsc = lv_img_cache_open(src, draw_dsc->recolor);
|
||||
lv_img_cache_entry_t * cdsc = _lv_img_cache_open(src, draw_dsc->recolor);
|
||||
|
||||
if(cdsc == NULL) return LV_RES_INV;
|
||||
|
||||
@@ -245,7 +242,7 @@ LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords,
|
||||
if(cdsc->dec_dsc.error_msg != NULL) {
|
||||
LV_LOG_WARN("Image draw error");
|
||||
|
||||
show_error(coords, mask, cdsc->dec_dsc.error_msg);
|
||||
show_error(coords, clip_area, cdsc->dec_dsc.error_msg);
|
||||
}
|
||||
/* The decoder could open the image and gave the entire uncompressed image.
|
||||
* Just draw it!*/
|
||||
@@ -256,7 +253,7 @@ LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords,
|
||||
int32_t w = lv_area_get_width(coords);
|
||||
int32_t h = lv_area_get_height(coords);
|
||||
|
||||
lv_img_buf_get_transformed_area(&map_area_rot, w, h, draw_dsc->angle, draw_dsc->zoom, &draw_dsc->pivot);
|
||||
_lv_img_buf_get_transformed_area(&map_area_rot, w, h, draw_dsc->angle, draw_dsc->zoom, &draw_dsc->pivot);
|
||||
|
||||
map_area_rot.x1 += coords->x1;
|
||||
map_area_rot.y1 += coords->y1;
|
||||
@@ -266,7 +263,7 @@ LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords,
|
||||
|
||||
lv_area_t mask_com; /*Common area of mask and coords*/
|
||||
bool union_ok;
|
||||
union_ok = lv_area_intersect(&mask_com, mask, &map_area_rot);
|
||||
union_ok = _lv_area_intersect(&mask_com, clip_area, &map_area_rot);
|
||||
if(union_ok == false) {
|
||||
return LV_RES_OK; /*Out of mask. There is nothing to draw so the image is drawn
|
||||
successfully.*/
|
||||
@@ -278,7 +275,7 @@ LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords,
|
||||
else {
|
||||
lv_area_t mask_com; /*Common area of mask and coords*/
|
||||
bool union_ok;
|
||||
union_ok = lv_area_intersect(&mask_com, mask, coords);
|
||||
union_ok = _lv_area_intersect(&mask_com, clip_area, coords);
|
||||
if(union_ok == false) {
|
||||
return LV_RES_OK; /*Out of mask. There is nothing to draw so the image is drawn
|
||||
successfully.*/
|
||||
@@ -286,8 +283,8 @@ LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords,
|
||||
|
||||
int32_t width = lv_area_get_width(&mask_com);
|
||||
|
||||
uint8_t * buf = lv_mem_buf_get(lv_area_get_width(&mask_com) *
|
||||
LV_IMG_PX_SIZE_ALPHA_BYTE); /*+1 because of the possible alpha byte*/
|
||||
uint8_t * buf = _lv_mem_buf_get(lv_area_get_width(&mask_com) *
|
||||
LV_IMG_PX_SIZE_ALPHA_BYTE); /*+1 because of the possible alpha byte*/
|
||||
|
||||
lv_area_t line;
|
||||
lv_area_copy(&line, &mask_com);
|
||||
@@ -298,14 +295,14 @@ LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords,
|
||||
lv_res_t read_res;
|
||||
for(row = mask_com.y1; row <= mask_com.y2; row++) {
|
||||
lv_area_t mask_line;
|
||||
union_ok = lv_area_intersect(&mask_line, mask, &line);
|
||||
union_ok = _lv_area_intersect(&mask_line, clip_area, &line);
|
||||
if(union_ok == false) continue;
|
||||
|
||||
read_res = lv_img_decoder_read_line(&cdsc->dec_dsc, x, y, width, buf);
|
||||
if(read_res != LV_RES_OK) {
|
||||
lv_img_decoder_close(&cdsc->dec_dsc);
|
||||
LV_LOG_WARN("Image draw can't read the line");
|
||||
lv_mem_buf_release(buf);
|
||||
_lv_mem_buf_release(buf);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
@@ -315,7 +312,7 @@ LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords,
|
||||
line.y2++;
|
||||
y++;
|
||||
}
|
||||
lv_mem_buf_release(buf);
|
||||
_lv_mem_buf_release(buf);
|
||||
}
|
||||
|
||||
return LV_RES_OK;
|
||||
@@ -326,23 +323,20 @@ LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords,
|
||||
* @param cords_p coordinates the color map
|
||||
* @param mask_p the map will drawn only on this area (truncated to VDB area)
|
||||
* @param map_p pointer to a lv_color_t array
|
||||
* @param opa opacity of the map
|
||||
* @param draw_dsc pointer to an initialized `lv_draw_img_dsc_t` variable
|
||||
* @param chroma_keyed true: enable transparency of LV_IMG_LV_COLOR_TRANSP color pixels
|
||||
* @param alpha_byte true: extra alpha byte is inserted for every pixel
|
||||
* @param style style of the image
|
||||
* @param angle angle in degree
|
||||
* @param pivot center of rotation
|
||||
* @param zoom zoom factor
|
||||
* @param antialias anti-alias transformations (rotate, zoom) or not
|
||||
*/
|
||||
LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const lv_area_t * clip_area, const uint8_t * map_p,
|
||||
lv_draw_img_dsc_t * draw_dsc, bool chroma_key, bool alpha_byte)
|
||||
LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const lv_area_t * clip_area,
|
||||
const uint8_t * map_p,
|
||||
const lv_draw_img_dsc_t * draw_dsc,
|
||||
bool chroma_key, bool alpha_byte)
|
||||
{
|
||||
/* Use the clip area as draw area*/
|
||||
lv_area_t draw_area;
|
||||
lv_area_copy(&draw_area, clip_area);
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
const lv_area_t * disp_area = &vdb->area;
|
||||
|
||||
@@ -358,22 +352,16 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const
|
||||
/*The simplest case just copy the pixels into the VDB*/
|
||||
if(other_mask_cnt == 0 && draw_dsc->angle == 0 && draw_dsc->zoom == LV_IMG_ZOOM_NONE &&
|
||||
chroma_key == false && alpha_byte == false && draw_dsc->recolor_opa == LV_OPA_TRANSP) {
|
||||
lv_blend_map(clip_area, map_area, (lv_color_t *)map_p, NULL, LV_DRAW_MASK_RES_FULL_COVER, draw_dsc->opa,
|
||||
draw_dsc->blend_mode);
|
||||
_lv_blend_map(clip_area, map_area, (lv_color_t *)map_p, NULL, LV_DRAW_MASK_RES_FULL_COVER, draw_dsc->opa,
|
||||
draw_dsc->blend_mode);
|
||||
}
|
||||
/*In the other cases every pixel need to be checked one-by-one*/
|
||||
else {
|
||||
/*The pixel size in byte is different if an alpha byte is added too*/
|
||||
uint8_t px_size_byte = alpha_byte ? LV_IMG_PX_SIZE_ALPHA_BYTE : sizeof(lv_color_t);
|
||||
|
||||
/*Build the image and a mask line-by-line*/
|
||||
uint32_t mask_buf_size = lv_area_get_size(&draw_area) > LV_HOR_RES_MAX ? LV_HOR_RES_MAX : lv_area_get_size(&draw_area);
|
||||
lv_color_t * map2 = lv_mem_buf_get(mask_buf_size * sizeof(lv_color_t));
|
||||
lv_opa_t * mask_buf = lv_mem_buf_get(mask_buf_size);
|
||||
|
||||
/*Go to the first displayed pixel of the map*/
|
||||
int32_t map_w = lv_area_get_width(map_area);
|
||||
int32_t map_h = lv_area_get_height(map_area);
|
||||
const uint8_t * map_buf_tmp = map_p;
|
||||
map_buf_tmp += map_w * (draw_area.y1 - (map_area->y1 - disp_area->y1)) * px_size_byte;
|
||||
map_buf_tmp += (draw_area.x1 - (map_area->x1 - disp_area->x1)) * px_size_byte;
|
||||
@@ -393,8 +381,11 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const
|
||||
lv_coord_t draw_area_h = lv_area_get_height(&draw_area);
|
||||
lv_coord_t draw_area_w = lv_area_get_width(&draw_area);
|
||||
|
||||
#if LV_USE_IMG_TRANSFORM
|
||||
bool transform = draw_dsc->angle != 0 || draw_dsc->zoom != LV_IMG_ZOOM_NONE ? true : false;
|
||||
|
||||
#else
|
||||
bool transform = false;
|
||||
#endif
|
||||
/*Simple ARGB image. Handle it as special case because it's very common*/
|
||||
if(other_mask_cnt == 0 && !transform && !chroma_key && draw_dsc->recolor_opa == LV_OPA_TRANSP && alpha_byte) {
|
||||
#if LV_USE_GPU_STM32_DMA2D && LV_COLOR_DEPTH == 32
|
||||
@@ -403,10 +394,15 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const
|
||||
int32_t disp_w = lv_area_get_width(disp_area);
|
||||
lv_color_t * disp_buf = vdb->buf_act;
|
||||
lv_color_t * disp_buf_first = disp_buf + disp_w * draw_area.y1 + draw_area.x1;
|
||||
lv_gpu_stm32_dma2d_blend(disp_buf_first, disp_w, (const lv_color_t *)map_buf_tmp, draw_dsc->opa, map_w, draw_area_w, draw_area_h);
|
||||
lv_gpu_stm32_dma2d_blend(disp_buf_first, disp_w, (const lv_color_t *)map_buf_tmp, draw_dsc->opa, map_w, draw_area_w,
|
||||
draw_area_h);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
uint32_t mask_buf_size = lv_area_get_size(&draw_area) > LV_HOR_RES_MAX ? LV_HOR_RES_MAX : lv_area_get_size(&draw_area);
|
||||
lv_color_t * map2 = _lv_mem_buf_get(mask_buf_size * sizeof(lv_color_t));
|
||||
lv_opa_t * mask_buf = _lv_mem_buf_get(mask_buf_size);
|
||||
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
for(y = 0; y < draw_area_h; y++) {
|
||||
@@ -415,16 +411,17 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const
|
||||
lv_opa_t px_opa = map_px[LV_IMG_PX_SIZE_ALPHA_BYTE - 1];
|
||||
mask_buf[px_i] = px_opa;
|
||||
if(px_opa) {
|
||||
#if LV_COLOR_DEPTH == 8
|
||||
c.full = map_px[0];
|
||||
#if LV_COLOR_DEPTH == 8 || LV_COLOR_DEPTH == 1
|
||||
map2[px_i].full = map_px[0];
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
c.full = map_px[0] + (map_px[1] << 8);
|
||||
map2[px_i].full = map_px[0] + (map_px[1] << 8);
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
c.full = *((uint32_t *)map_px);
|
||||
c.ch.alpha = 0xFF;
|
||||
map2[px_i].full = *((uint32_t *)map_px);
|
||||
#endif
|
||||
map2[px_i].full = c.full;
|
||||
}
|
||||
#if LV_COLOR_DEPTH == 32
|
||||
map2[px_i].ch.alpha = 0xFF;
|
||||
#endif
|
||||
}
|
||||
|
||||
map_buf_tmp += map_w * px_size_byte;
|
||||
@@ -432,7 +429,7 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const
|
||||
blend_area.y2 ++;
|
||||
}
|
||||
else {
|
||||
lv_blend_map(clip_area, &blend_area, map2, mask_buf, LV_DRAW_MASK_RES_CHANGED, draw_dsc->opa, draw_dsc->blend_mode);
|
||||
_lv_blend_map(clip_area, &blend_area, map2, mask_buf, LV_DRAW_MASK_RES_CHANGED, draw_dsc->opa, draw_dsc->blend_mode);
|
||||
|
||||
blend_area.y1 = blend_area.y2 + 1;
|
||||
blend_area.y2 = blend_area.y1;
|
||||
@@ -443,16 +440,22 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const
|
||||
/*Flush the last part*/
|
||||
if(blend_area.y1 != blend_area.y2) {
|
||||
blend_area.y2--;
|
||||
lv_blend_map(clip_area, &blend_area, map2, mask_buf, LV_DRAW_MASK_RES_CHANGED, draw_dsc->opa, draw_dsc->blend_mode);
|
||||
_lv_blend_map(clip_area, &blend_area, map2, mask_buf, LV_DRAW_MASK_RES_CHANGED, draw_dsc->opa, draw_dsc->blend_mode);
|
||||
}
|
||||
|
||||
lv_mem_buf_release(mask_buf);
|
||||
lv_mem_buf_release(map2);
|
||||
_lv_mem_buf_release(mask_buf);
|
||||
_lv_mem_buf_release(map2);
|
||||
}
|
||||
/*Most complicated case: transform or other mask or chroma keyed*/
|
||||
else {
|
||||
/*Build the image and a mask line-by-line*/
|
||||
uint32_t mask_buf_size = lv_area_get_size(&draw_area) > LV_HOR_RES_MAX ? LV_HOR_RES_MAX : lv_area_get_size(&draw_area);
|
||||
lv_color_t * map2 = _lv_mem_buf_get(mask_buf_size * sizeof(lv_color_t));
|
||||
lv_opa_t * mask_buf = _lv_mem_buf_get(mask_buf_size);
|
||||
|
||||
#if LV_USE_IMG_TRANSFORM
|
||||
lv_img_transform_dsc_t trans_dsc;
|
||||
lv_memset_00(&trans_dsc, sizeof(lv_img_transform_dsc_t));
|
||||
_lv_memset_00(&trans_dsc, sizeof(lv_img_transform_dsc_t));
|
||||
if(transform) {
|
||||
lv_img_cf_t cf = LV_IMG_CF_TRUE_COLOR;
|
||||
if(alpha_byte) cf = LV_IMG_CF_TRUE_COLOR_ALPHA;
|
||||
@@ -462,16 +465,16 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const
|
||||
trans_dsc.cfg.zoom = draw_dsc->zoom;
|
||||
trans_dsc.cfg.src = map_p;
|
||||
trans_dsc.cfg.src_w = map_w;
|
||||
trans_dsc.cfg.src_h = map_h;
|
||||
trans_dsc.cfg.src_h = lv_area_get_height(map_area);;
|
||||
trans_dsc.cfg.cf = cf;
|
||||
trans_dsc.cfg.pivot_x = draw_dsc->pivot.x;
|
||||
trans_dsc.cfg.pivot_y = draw_dsc->pivot.y;
|
||||
trans_dsc.cfg.color = draw_dsc->recolor;
|
||||
trans_dsc.cfg.antialias = draw_dsc->antialias;
|
||||
|
||||
lv_img_buf_transform_init(&trans_dsc);
|
||||
_lv_img_buf_transform_init(&trans_dsc);
|
||||
}
|
||||
|
||||
#endif
|
||||
uint16_t recolor_premult[3] = {0};
|
||||
lv_opa_t recolor_opa_inv = 255 - draw_dsc->recolor_opa;
|
||||
if(draw_dsc->recolor_opa != 0) {
|
||||
@@ -479,34 +482,66 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const
|
||||
}
|
||||
|
||||
lv_draw_mask_res_t mask_res;
|
||||
mask_res = (alpha_byte || chroma_key || draw_dsc->angle || draw_dsc->zoom != LV_IMG_ZOOM_NONE) ? LV_DRAW_MASK_RES_CHANGED : LV_DRAW_MASK_RES_FULL_COVER;
|
||||
mask_res = (alpha_byte || chroma_key || draw_dsc->angle ||
|
||||
draw_dsc->zoom != LV_IMG_ZOOM_NONE) ? LV_DRAW_MASK_RES_CHANGED : LV_DRAW_MASK_RES_FULL_COVER;
|
||||
|
||||
|
||||
/*Prepare the `mask_buf`if there are other masks*/
|
||||
if(other_mask_cnt) {
|
||||
lv_memset_ff(mask_buf, mask_buf_size);
|
||||
_lv_memset_ff(mask_buf, mask_buf_size);
|
||||
}
|
||||
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
#if LV_USE_IMG_TRANSFORM
|
||||
int32_t rot_y = disp_area->y1 + draw_area.y1 - map_area->y1;
|
||||
#endif
|
||||
for(y = 0; y < draw_area_h; y++) {
|
||||
map_px = map_buf_tmp;
|
||||
uint32_t px_i_start = px_i;
|
||||
|
||||
#if LV_USE_IMG_TRANSFORM
|
||||
int32_t rot_x = disp_area->x1 + draw_area.x1 - map_area->x1;
|
||||
#endif
|
||||
for(x = 0; x < draw_area_w; x++, map_px += px_size_byte, px_i++) {
|
||||
|
||||
if(transform == false) {
|
||||
|
||||
#if LV_USE_IMG_TRANSFORM
|
||||
if(transform) {
|
||||
|
||||
/*Transform*/
|
||||
bool ret;
|
||||
ret = _lv_img_buf_transform(&trans_dsc, rot_x + x, rot_y + y);
|
||||
if(ret == false) {
|
||||
mask_buf[px_i] = LV_OPA_TRANSP;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
mask_buf[px_i] = trans_dsc.res.opa;
|
||||
c.full = trans_dsc.res.color.full;
|
||||
}
|
||||
}
|
||||
/*No transform*/
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if(alpha_byte) {
|
||||
lv_opa_t px_opa = map_px[LV_IMG_PX_SIZE_ALPHA_BYTE - 1];
|
||||
mask_buf[px_i] = px_opa;
|
||||
if(px_opa < LV_OPA_MIN) {
|
||||
if(px_opa == 0) {
|
||||
#if LV_COLOR_DEPTH == 32
|
||||
map2[px_i].full = 0;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
mask_buf[px_i] = 0xFF;
|
||||
}
|
||||
|
||||
#if LV_COLOR_DEPTH == 8
|
||||
#if LV_COLOR_DEPTH == 1
|
||||
c.full = map_px[0];
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
c.full = map_px[0];
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
c.full = map_px[0] + (map_px[1] << 8);
|
||||
@@ -517,25 +552,13 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const
|
||||
if(chroma_key) {
|
||||
if(c.full == chroma_keyed_color.full) {
|
||||
mask_buf[px_i] = LV_OPA_TRANSP;
|
||||
#if LV_COLOR_DEPTH == 32
|
||||
map2[px_i].full = 0;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*Transform*/
|
||||
bool ret;
|
||||
int32_t rot_x = x + (disp_area->x1 + draw_area.x1) - map_area->x1;
|
||||
int32_t rot_y = y + (disp_area->y1 + draw_area.y1) - map_area->y1;
|
||||
ret = lv_img_buf_transform(&trans_dsc, rot_x, rot_y);
|
||||
if(ret == false) {
|
||||
mask_buf[px_i] = LV_OPA_TRANSP;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
mask_buf[px_i] = trans_dsc.res.opa;
|
||||
c.full = trans_dsc.res.color.full;
|
||||
}
|
||||
}
|
||||
|
||||
if(draw_dsc->recolor_opa != 0) {
|
||||
c = lv_color_mix_premult(recolor_premult, c, recolor_opa_inv);
|
||||
@@ -550,7 +573,7 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const
|
||||
mask_res_sub = lv_draw_mask_apply(mask_buf + px_i_start, draw_area.x1 + vdb->area.x1, y + draw_area.y1 + vdb->area.y1,
|
||||
lv_area_get_width(&draw_area));
|
||||
if(mask_res_sub == LV_DRAW_MASK_RES_TRANSP) {
|
||||
lv_memset_00(mask_buf + px_i_start, lv_area_get_width(&draw_area));
|
||||
_lv_memset_00(mask_buf + px_i_start, lv_area_get_width(&draw_area));
|
||||
mask_res = LV_DRAW_MASK_RES_CHANGED;
|
||||
}
|
||||
else if(mask_res_sub == LV_DRAW_MASK_RES_CHANGED) {
|
||||
@@ -563,29 +586,32 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const
|
||||
blend_area.y2 ++;
|
||||
}
|
||||
else {
|
||||
lv_blend_map(clip_area, &blend_area, map2, mask_buf, mask_res, draw_dsc->opa, draw_dsc->blend_mode);
|
||||
|
||||
_lv_blend_map(clip_area, &blend_area, map2, mask_buf, mask_res, draw_dsc->opa, draw_dsc->blend_mode);
|
||||
|
||||
blend_area.y1 = blend_area.y2 + 1;
|
||||
blend_area.y2 = blend_area.y1;
|
||||
|
||||
px_i = 0;
|
||||
mask_res = (alpha_byte || chroma_key || draw_dsc->angle || draw_dsc->zoom != LV_IMG_ZOOM_NONE) ? LV_DRAW_MASK_RES_CHANGED : LV_DRAW_MASK_RES_FULL_COVER;
|
||||
mask_res = (alpha_byte || chroma_key || draw_dsc->angle ||
|
||||
draw_dsc->zoom != LV_IMG_ZOOM_NONE) ? LV_DRAW_MASK_RES_CHANGED : LV_DRAW_MASK_RES_FULL_COVER;
|
||||
|
||||
/*Prepare the `mask_buf`if there are other masks*/
|
||||
if(other_mask_cnt) {
|
||||
lv_memset_ff(mask_buf, mask_buf_size);
|
||||
_lv_memset_ff(mask_buf, mask_buf_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*Flush the last part*/
|
||||
if(blend_area.y1 != blend_area.y2) {
|
||||
blend_area.y2--;
|
||||
lv_blend_map(clip_area, &blend_area, map2, mask_buf, mask_res, draw_dsc->opa, draw_dsc->blend_mode);
|
||||
_lv_blend_map(clip_area, &blend_area, map2, mask_buf, mask_res, draw_dsc->opa, draw_dsc->blend_mode);
|
||||
}
|
||||
}
|
||||
|
||||
lv_mem_buf_release(mask_buf);
|
||||
lv_mem_buf_release(map2);
|
||||
_lv_mem_buf_release(mask_buf);
|
||||
_lv_mem_buf_release(map2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,13 +53,9 @@ void lv_draw_img_dsc_init(lv_draw_img_dsc_t * dsc);
|
||||
* @param coords the coordinates of the image
|
||||
* @param mask the image will be drawn only in this area
|
||||
* @param src pointer to a lv_color_t array which contains the pixels of the image
|
||||
* @param style style of the image
|
||||
* @param angle rotation angle of the image
|
||||
* @param center rotation center of the image
|
||||
* @param antialias anti-alias transformations (rotate, zoom) or not
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
* @param dsc pointer to an initialized `lv_draw_img_dsc_t` variable
|
||||
*/
|
||||
void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * src, lv_draw_img_dsc_t * dsc);
|
||||
void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * src, const lv_draw_img_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Get the type of an image source
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "../lv_hal/lv_hal_disp.h"
|
||||
#include "../lv_core/lv_refr.h"
|
||||
#include "../lv_misc/lv_bidi.h"
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "../lv_misc/lv_debug.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -32,10 +32,12 @@ typedef uint8_t cmd_state_t;
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
LV_ATTRIBUTE_FAST_MEM static void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * clip_area, const lv_font_t * font_p,
|
||||
uint32_t letter, lv_color_t color, lv_opa_t opa, lv_blend_mode_t blend_mode);
|
||||
LV_ATTRIBUTE_FAST_MEM static void draw_letter_normal(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_dsc_t * g, const lv_area_t * clip_area,
|
||||
const uint8_t * map_p, lv_color_t color, lv_opa_t opa, lv_blend_mode_t blend_mode);
|
||||
LV_ATTRIBUTE_FAST_MEM static void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * clip_area,
|
||||
const lv_font_t * font_p,
|
||||
uint32_t letter, lv_color_t color, lv_opa_t opa, lv_blend_mode_t blend_mode);
|
||||
LV_ATTRIBUTE_FAST_MEM static void draw_letter_normal(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_dsc_t * g,
|
||||
const lv_area_t * clip_area,
|
||||
const uint8_t * map_p, lv_color_t color, lv_opa_t opa, lv_blend_mode_t blend_mode);
|
||||
static void draw_letter_subpx(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_dsc_t * g, const lv_area_t * clip_area,
|
||||
const uint8_t * map_p, lv_color_t color, lv_opa_t opa, lv_blend_mode_t blend_mode);
|
||||
|
||||
@@ -54,30 +56,31 @@ const uint8_t _lv_bpp1_opa_table[2] = {0, 255}; /*Opacity mapping with
|
||||
const uint8_t _lv_bpp2_opa_table[4] = {0, 85, 170, 255}; /*Opacity mapping with bpp = 2*/
|
||||
|
||||
const uint8_t _lv_bpp3_opa_table[8] = {0, 36, 73, 109, /*Opacity mapping with bpp = 3*/
|
||||
146, 182, 219, 255};
|
||||
146, 182, 219, 255
|
||||
};
|
||||
|
||||
const uint8_t _lv_bpp4_opa_table[16] = {0, 17, 34, 51, /*Opacity mapping with bpp = 4*/
|
||||
68, 85, 102, 119,
|
||||
136, 153, 170, 187,
|
||||
204, 221, 238, 255
|
||||
};
|
||||
68, 85, 102, 119,
|
||||
136, 153, 170, 187,
|
||||
204, 221, 238, 255
|
||||
};
|
||||
const uint8_t _lv_bpp8_opa_table[256] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
||||
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
|
||||
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
|
||||
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
|
||||
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
|
||||
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
|
||||
160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
|
||||
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
|
||||
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
|
||||
208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
|
||||
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
|
||||
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
|
||||
};
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
||||
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
|
||||
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
|
||||
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
|
||||
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
|
||||
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
|
||||
160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
|
||||
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
|
||||
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
|
||||
208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
|
||||
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
|
||||
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
|
||||
};
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
@@ -89,7 +92,7 @@ const uint8_t _lv_bpp8_opa_table[256] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 1
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM void lv_draw_label_dsc_init(lv_draw_label_dsc_t * dsc)
|
||||
{
|
||||
lv_memset_00(dsc, sizeof(lv_draw_label_dsc_t));
|
||||
_lv_memset_00(dsc, sizeof(lv_draw_label_dsc_t));
|
||||
dsc->opa = LV_OPA_COVER;
|
||||
dsc->color = LV_COLOR_BLACK;
|
||||
dsc->font = LV_THEME_DEFAULT_FONT_NORMAL;
|
||||
@@ -105,9 +108,13 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_label_dsc_init(lv_draw_label_dsc_t * dsc)
|
||||
* @param mask the label will be drawn only in this area
|
||||
* @param dsc pointer to draw descriptor
|
||||
* @param txt `\0` terminated text to write
|
||||
* @param hint pointer to a `lv_draw_label_hint_t` variable.
|
||||
* It is managed by the drawer to speed up the drawing of very long texts (thousands of lines).
|
||||
*/
|
||||
LV_ATTRIBUTE_FAST_MEM void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, lv_draw_label_dsc_t * dsc,
|
||||
const char * txt, lv_draw_label_hint_t * hint)
|
||||
LV_ATTRIBUTE_FAST_MEM void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask,
|
||||
const lv_draw_label_dsc_t * dsc,
|
||||
const char * txt,
|
||||
lv_draw_label_hint_t * hint)
|
||||
{
|
||||
|
||||
if(dsc->opa <= LV_OPA_MIN) return;
|
||||
@@ -118,7 +125,7 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_label(const lv_area_t * coords, const lv_area
|
||||
if(txt[0] == '\0') return;
|
||||
|
||||
lv_area_t clipped_area;
|
||||
bool clip_ok = lv_area_intersect(&clipped_area, coords, mask);
|
||||
bool clip_ok = _lv_area_intersect(&clipped_area, coords, mask);
|
||||
if(!clip_ok) return;
|
||||
|
||||
|
||||
@@ -129,8 +136,8 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_label(const lv_area_t * coords, const lv_area
|
||||
else {
|
||||
/*If EXAPND is enabled then not limit the text's width to the object's width*/
|
||||
lv_point_t p;
|
||||
lv_txt_get_size(&p, txt, dsc->font, dsc->letter_space, dsc->line_space, LV_COORD_MAX,
|
||||
dsc->flag);
|
||||
_lv_txt_get_size(&p, txt, dsc->font, dsc->letter_space, dsc->line_space, LV_COORD_MAX,
|
||||
dsc->flag);
|
||||
w = p.x;
|
||||
}
|
||||
|
||||
@@ -167,13 +174,13 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_label(const lv_area_t * coords, const lv_area
|
||||
pos.y += hint->y;
|
||||
}
|
||||
|
||||
uint32_t line_end = line_start + lv_txt_get_next_line(&txt[line_start], font, dsc->letter_space, w, dsc->flag);
|
||||
uint32_t line_end = line_start + _lv_txt_get_next_line(&txt[line_start], font, dsc->letter_space, w, dsc->flag);
|
||||
|
||||
/*Go the first visible line*/
|
||||
while(pos.y + line_height_font < mask->y1) {
|
||||
/*Go to next line*/
|
||||
line_start = line_end;
|
||||
line_end += lv_txt_get_next_line(&txt[line_start], font, dsc->letter_space, w, dsc->flag);
|
||||
line_end += _lv_txt_get_next_line(&txt[line_start], font, dsc->letter_space, w, dsc->flag);
|
||||
pos.y += line_height;
|
||||
|
||||
/*Save at the threshold coordinate*/
|
||||
@@ -188,39 +195,39 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_label(const lv_area_t * coords, const lv_area
|
||||
|
||||
/*Align to middle*/
|
||||
if(dsc->flag & LV_TXT_FLAG_CENTER) {
|
||||
line_width = lv_txt_get_width(&txt[line_start], line_end - line_start, font, dsc->letter_space, dsc->flag);
|
||||
line_width = _lv_txt_get_width(&txt[line_start], line_end - line_start, font, dsc->letter_space, dsc->flag);
|
||||
|
||||
pos.x += (lv_area_get_width(coords) - line_width) / 2;
|
||||
|
||||
}
|
||||
/*Align to the right*/
|
||||
else if(dsc->flag & LV_TXT_FLAG_RIGHT) {
|
||||
line_width = lv_txt_get_width(&txt[line_start], line_end - line_start, font, dsc->letter_space, dsc->flag);
|
||||
line_width = _lv_txt_get_width(&txt[line_start], line_end - line_start, font, dsc->letter_space, dsc->flag);
|
||||
pos.x += lv_area_get_width(coords) - line_width;
|
||||
}
|
||||
|
||||
lv_opa_t opa = dsc->opa;
|
||||
|
||||
uint16_t sel_start = dsc->sel_start;
|
||||
uint16_t sel_end = dsc->sel_end;
|
||||
uint32_t sel_start = dsc->sel_start;
|
||||
uint32_t sel_end = dsc->sel_end;
|
||||
if(sel_start > sel_end) {
|
||||
uint16_t tmp = sel_start;
|
||||
uint32_t tmp = sel_start;
|
||||
sel_start = sel_end;
|
||||
sel_end = tmp;
|
||||
}
|
||||
|
||||
lv_draw_line_dsc_t line_dsc;
|
||||
|
||||
if((dsc->decor & LV_TEXT_DECOR_UNDERLINE) || (dsc->decor & LV_TEXT_DECOR_STRIKETHROUGH)) {
|
||||
lv_draw_line_dsc_init(&line_dsc);
|
||||
line_dsc.color = dsc->color;
|
||||
line_dsc.width = (dsc->font->line_height + 5) / 10; /*+5 for rounding*/
|
||||
line_dsc.width = font->underline_thickness ? font->underline_thickness : LV_MATH_MAX(font->line_height / 10, 1);
|
||||
line_dsc.opa = dsc->opa;
|
||||
line_dsc.blend_mode = dsc->blend_mode;
|
||||
}
|
||||
|
||||
cmd_state_t cmd_state = CMD_STATE_WAIT;
|
||||
uint32_t i;
|
||||
uint16_t par_start = 0;
|
||||
uint32_t par_start = 0;
|
||||
lv_color_t recolor;
|
||||
int32_t letter_w;
|
||||
|
||||
@@ -238,26 +245,26 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_label(const lv_area_t * coords, const lv_area
|
||||
cmd_state = CMD_STATE_WAIT;
|
||||
i = 0;
|
||||
#if LV_USE_BIDI
|
||||
char * bidi_txt = lv_mem_buf_get(line_end - line_start + 1);
|
||||
lv_bidi_process_paragraph(txt + line_start, bidi_txt, line_end - line_start, dsc->bidi_dir, NULL, 0);
|
||||
char * bidi_txt = _lv_mem_buf_get(line_end - line_start + 1);
|
||||
_lv_bidi_process_paragraph(txt + line_start, bidi_txt, line_end - line_start, dsc->bidi_dir, NULL, 0);
|
||||
#else
|
||||
const char * bidi_txt = txt + line_start;
|
||||
#endif
|
||||
|
||||
while(i < line_end - line_start) {
|
||||
uint16_t logical_char_pos = 0;
|
||||
uint32_t logical_char_pos = 0;
|
||||
if(sel_start != 0xFFFF && sel_end != 0xFFFF) {
|
||||
#if LV_USE_BIDI
|
||||
logical_char_pos = lv_txt_encoded_get_char_id(txt, line_start);
|
||||
uint16_t t = lv_txt_encoded_get_char_id(bidi_txt, i);
|
||||
logical_char_pos += lv_bidi_get_logical_pos(bidi_txt, NULL, line_end - line_start, dsc->bidi_dir, t, NULL);
|
||||
logical_char_pos = _lv_txt_encoded_get_char_id(txt, line_start);
|
||||
uint32_t t = _lv_txt_encoded_get_char_id(bidi_txt, i);
|
||||
logical_char_pos += _lv_bidi_get_logical_pos(bidi_txt, NULL, line_end - line_start, dsc->bidi_dir, t, NULL);
|
||||
#else
|
||||
logical_char_pos = lv_txt_encoded_get_char_id(txt, line_start + i);
|
||||
logical_char_pos = _lv_txt_encoded_get_char_id(txt, line_start + i);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t letter = lv_txt_encoded_next(bidi_txt, &i);
|
||||
uint32_t letter_next = lv_txt_encoded_next(&bidi_txt[i], NULL);
|
||||
uint32_t letter = _lv_txt_encoded_next(bidi_txt, &i);
|
||||
uint32_t letter_next = _lv_txt_encoded_next(&bidi_txt[i], NULL);
|
||||
|
||||
/*Handle the re-color command*/
|
||||
if((dsc->flag & LV_TXT_FLAG_RECOLOR) != 0) {
|
||||
@@ -282,7 +289,7 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_label(const lv_area_t * coords, const lv_area
|
||||
/*Get the parameter*/
|
||||
if(i - par_start == LABEL_RECOLOR_PAR_LENGTH + 1) {
|
||||
char buf[LABEL_RECOLOR_PAR_LENGTH + 1];
|
||||
lv_memcpy_small(buf, &bidi_txt[par_start], LABEL_RECOLOR_PAR_LENGTH);
|
||||
_lv_memcpy_small(buf, &bidi_txt[par_start], LABEL_RECOLOR_PAR_LENGTH);
|
||||
buf[LABEL_RECOLOR_PAR_LENGTH] = '\0';
|
||||
int r, g, b;
|
||||
r = (hex_char_to_num(buf[0]) << 4) + hex_char_to_num(buf[1]);
|
||||
@@ -337,25 +344,25 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_label(const lv_area_t * coords, const lv_area
|
||||
lv_point_t p1;
|
||||
lv_point_t p2;
|
||||
p1.x = pos_x_start;
|
||||
p1.y = pos.y + dsc->font->line_height - dsc->font->base_line + line_dsc.width / 2 + 1;
|
||||
p1.y = pos.y + dsc->font->line_height - dsc->font->base_line - font->underline_position;
|
||||
p2.x = pos.x;
|
||||
p2.y = p1.y;
|
||||
lv_draw_line(&p1, &p2, mask, &line_dsc);
|
||||
}
|
||||
|
||||
#if LV_USE_BIDI
|
||||
lv_mem_buf_release(bidi_txt);
|
||||
_lv_mem_buf_release(bidi_txt);
|
||||
bidi_txt = NULL;
|
||||
#endif
|
||||
/*Go to next line*/
|
||||
line_start = line_end;
|
||||
line_end += lv_txt_get_next_line(&txt[line_start], font, dsc->letter_space, w, dsc->flag);
|
||||
line_end += _lv_txt_get_next_line(&txt[line_start], font, dsc->letter_space, w, dsc->flag);
|
||||
|
||||
pos.x = coords->x1;
|
||||
/*Align to middle*/
|
||||
if(dsc->flag & LV_TXT_FLAG_CENTER) {
|
||||
line_width =
|
||||
lv_txt_get_width(&txt[line_start], line_end - line_start, font, dsc->letter_space, dsc->flag);
|
||||
_lv_txt_get_width(&txt[line_start], line_end - line_start, font, dsc->letter_space, dsc->flag);
|
||||
|
||||
pos.x += (lv_area_get_width(coords) - line_width) / 2;
|
||||
|
||||
@@ -363,7 +370,7 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_label(const lv_area_t * coords, const lv_area
|
||||
/*Align to the right*/
|
||||
else if(dsc->flag & LV_TXT_FLAG_RIGHT) {
|
||||
line_width =
|
||||
lv_txt_get_width(&txt[line_start], line_end - line_start, font, dsc->letter_space, dsc->flag);
|
||||
_lv_txt_get_width(&txt[line_start], line_end - line_start, font, dsc->letter_space, dsc->flag);
|
||||
pos.x += lv_area_get_width(coords) - line_width;
|
||||
}
|
||||
|
||||
@@ -390,9 +397,10 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_label(const lv_area_t * coords, const lv_area
|
||||
* @param color color of letter
|
||||
* @param opa opacity of letter (0..255)
|
||||
*/
|
||||
LV_ATTRIBUTE_FAST_MEM static void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * clip_area, const lv_font_t * font_p,
|
||||
uint32_t letter,
|
||||
lv_color_t color, lv_opa_t opa, lv_blend_mode_t blend_mode)
|
||||
LV_ATTRIBUTE_FAST_MEM static void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * clip_area,
|
||||
const lv_font_t * font_p,
|
||||
uint32_t letter,
|
||||
lv_color_t color, lv_opa_t opa, lv_blend_mode_t blend_mode)
|
||||
{
|
||||
if(opa < LV_OPA_MIN) return;
|
||||
if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;
|
||||
@@ -414,7 +422,7 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_letter(const lv_point_t * pos_p, const
|
||||
}
|
||||
|
||||
/* Don't draw anything if the character is empty. E.g. space */
|
||||
if((g.box_h == 0) && (g.box_w == 0)) return;
|
||||
if((g.box_h == 0) || (g.box_w == 0)) return;
|
||||
|
||||
int32_t pos_x = pos_p->x + g.ofs_x;
|
||||
int32_t pos_y = pos_p->y + (font_p->line_height - font_p->base_line) - g.box_h - g.ofs_y;
|
||||
@@ -443,8 +451,9 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_letter(const lv_point_t * pos_p, const
|
||||
}
|
||||
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM static void draw_letter_normal(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_dsc_t * g, const lv_area_t * clip_area,
|
||||
const uint8_t * map_p, lv_color_t color, lv_opa_t opa, lv_blend_mode_t blend_mode)
|
||||
LV_ATTRIBUTE_FAST_MEM static void draw_letter_normal(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_dsc_t * g,
|
||||
const lv_area_t * clip_area,
|
||||
const uint8_t * map_p, lv_color_t color, lv_opa_t opa, lv_blend_mode_t blend_mode)
|
||||
{
|
||||
const uint8_t * bpp_opa_table_p;
|
||||
uint32_t bitmask_init;
|
||||
@@ -513,8 +522,8 @@ LV_ATTRIBUTE_FAST_MEM static void draw_letter_normal(lv_coord_t pos_x, lv_coord_
|
||||
uint32_t col_bit;
|
||||
col_bit = bit_ofs & 0x7; /* "& 0x7" equals to "% 8" just faster */
|
||||
|
||||
uint32_t mask_buf_size = box_w * box_h > LV_HOR_RES_MAX ? box_w * box_h : LV_HOR_RES_MAX;
|
||||
lv_opa_t * mask_buf = lv_mem_buf_get(mask_buf_size);
|
||||
uint32_t mask_buf_size = box_w * box_h > LV_HOR_RES_MAX ? LV_HOR_RES_MAX : box_w * box_h;
|
||||
lv_opa_t * mask_buf = _lv_mem_buf_get(mask_buf_size);
|
||||
int32_t mask_p = 0;
|
||||
|
||||
lv_area_t fill_area;
|
||||
@@ -563,17 +572,17 @@ LV_ATTRIBUTE_FAST_MEM static void draw_letter_normal(lv_coord_t pos_x, lv_coord_
|
||||
lv_draw_mask_res_t mask_res = lv_draw_mask_apply(mask_buf + mask_p_start, fill_area.x1, fill_area.y2,
|
||||
lv_area_get_width(&fill_area));
|
||||
if(mask_res == LV_DRAW_MASK_RES_TRANSP) {
|
||||
lv_memset_00(mask_buf + mask_p_start, lv_area_get_width(&fill_area));
|
||||
_lv_memset_00(mask_buf + mask_p_start, lv_area_get_width(&fill_area));
|
||||
}
|
||||
}
|
||||
|
||||
if((uint32_t) mask_p + (row_end - row_start) < mask_buf_size) {
|
||||
if((uint32_t) mask_p + (col_end - col_start) < mask_buf_size) {
|
||||
fill_area.y2 ++;
|
||||
}
|
||||
else {
|
||||
lv_blend_fill(clip_area, &fill_area,
|
||||
color, mask_buf, LV_DRAW_MASK_RES_CHANGED, LV_OPA_COVER,
|
||||
blend_mode);
|
||||
_lv_blend_fill(clip_area, &fill_area,
|
||||
color, mask_buf, LV_DRAW_MASK_RES_CHANGED, LV_OPA_COVER,
|
||||
blend_mode);
|
||||
|
||||
fill_area.y1 = fill_area.y2 + 1;
|
||||
fill_area.y2 = fill_area.y1;
|
||||
@@ -588,18 +597,19 @@ LV_ATTRIBUTE_FAST_MEM static void draw_letter_normal(lv_coord_t pos_x, lv_coord_
|
||||
/*Flush the last part*/
|
||||
if(fill_area.y1 != fill_area.y2) {
|
||||
fill_area.y2--;
|
||||
lv_blend_fill(clip_area, &fill_area,
|
||||
color, mask_buf, LV_DRAW_MASK_RES_CHANGED, LV_OPA_COVER,
|
||||
blend_mode);
|
||||
_lv_blend_fill(clip_area, &fill_area,
|
||||
color, mask_buf, LV_DRAW_MASK_RES_CHANGED, LV_OPA_COVER,
|
||||
blend_mode);
|
||||
mask_p = 0;
|
||||
}
|
||||
|
||||
lv_mem_buf_release(mask_buf);
|
||||
_lv_mem_buf_release(mask_buf);
|
||||
}
|
||||
|
||||
static void draw_letter_subpx(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_dsc_t * g, const lv_area_t * clip_area,
|
||||
const uint8_t * map_p, lv_color_t color, lv_opa_t opa, lv_blend_mode_t blend_mode)
|
||||
{
|
||||
#if LV_USE_FONT_SUBPX
|
||||
const uint8_t * bpp_opa_table;
|
||||
uint32_t bitmask_init;
|
||||
uint32_t bitmask;
|
||||
@@ -650,13 +660,13 @@ static void draw_letter_subpx(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_
|
||||
int32_t col_bit;
|
||||
col_bit = bit_ofs & 0x7; /* "& 0x7" equals to "% 8" just faster */
|
||||
|
||||
int32_t mask_buf_size = box_w * box_h > LV_HOR_RES_MAX ? g->box_w * g->box_h : LV_HOR_RES_MAX;
|
||||
lv_opa_t * mask_buf = lv_mem_buf_get(mask_buf_size);
|
||||
int32_t mask_buf_size = box_w * box_h > LV_HOR_RES_MAX ? LV_HOR_RES_MAX : g->box_w * g->box_h;
|
||||
lv_opa_t * mask_buf = _lv_mem_buf_get(mask_buf_size);
|
||||
int32_t mask_p = 0;
|
||||
|
||||
lv_color_t * color_buf = lv_mem_buf_get(mask_buf_size * sizeof(lv_color_t));
|
||||
lv_color_t * color_buf = _lv_mem_buf_get(mask_buf_size * sizeof(lv_color_t));
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
|
||||
int32_t vdb_width = lv_area_get_width(&vdb->area);
|
||||
@@ -722,7 +732,7 @@ static void draw_letter_subpx(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_
|
||||
#endif
|
||||
|
||||
#if LV_FONT_SUBPX_BGR
|
||||
res_color.ch.blue = (uint326_t)((uint32_t)txt_rgb[0] * font_rgb[0] + (bg_rgb[0] * (255 - font_rgb[0]))) >> 8;
|
||||
res_color.ch.blue = (uint32_t)((uint32_t)txt_rgb[0] * font_rgb[0] + (bg_rgb[0] * (255 - font_rgb[0]))) >> 8;
|
||||
res_color.ch.red = (uint32_t)((uint32_t)txt_rgb[2] * font_rgb[2] + (bg_rgb[2] * (255 - font_rgb[2]))) >> 8;
|
||||
#else
|
||||
res_color.ch.red = (uint32_t)((uint16_t)txt_rgb[0] * font_rgb[0] + (bg_rgb[0] * (255 - font_rgb[0]))) >> 8;
|
||||
@@ -737,6 +747,10 @@ static void draw_letter_subpx(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_
|
||||
res_color.ch.green_l = green & 0x7;
|
||||
#endif
|
||||
|
||||
#if LV_COLOR_DEPTH == 32
|
||||
res_color.ch.alpha = 0xff;
|
||||
#endif
|
||||
|
||||
if(font_rgb[0] == 0 && font_rgb[1] == 0 && font_rgb[2] == 0) mask_buf[mask_p] = LV_OPA_TRANSP;
|
||||
else mask_buf[mask_p] = LV_OPA_COVER;
|
||||
color_buf[mask_p] = res_color;
|
||||
@@ -747,7 +761,7 @@ static void draw_letter_subpx(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_
|
||||
}
|
||||
|
||||
/*Go to the next column*/
|
||||
if(col_bit < 8 - bpp) {
|
||||
if(col_bit < (int32_t)(8 - bpp)) {
|
||||
col_bit += bpp;
|
||||
bitmask = bitmask >> bpp;
|
||||
}
|
||||
@@ -763,15 +777,15 @@ static void draw_letter_subpx(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_
|
||||
lv_draw_mask_res_t mask_res = lv_draw_mask_apply(mask_buf + mask_p_start, map_area.x1, map_area.y2,
|
||||
lv_area_get_width(&map_area));
|
||||
if(mask_res == LV_DRAW_MASK_RES_TRANSP) {
|
||||
lv_memset_00(mask_buf + mask_p_start, lv_area_get_width(&map_area));
|
||||
_lv_memset_00(mask_buf + mask_p_start, lv_area_get_width(&map_area));
|
||||
}
|
||||
}
|
||||
|
||||
if((uint32_t) mask_p + (row_end - row_start) < mask_buf_size) {
|
||||
if((int32_t) mask_p + (col_end - col_start) < mask_buf_size) {
|
||||
map_area.y2 ++;
|
||||
}
|
||||
else {
|
||||
lv_blend_map(clip_area, &map_area, color_buf, mask_buf, LV_DRAW_MASK_RES_CHANGED, opa, blend_mode);
|
||||
_lv_blend_map(clip_area, &map_area, color_buf, mask_buf, LV_DRAW_MASK_RES_CHANGED, opa, blend_mode);
|
||||
|
||||
map_area.y1 = map_area.y2 + 1;
|
||||
map_area.y2 = map_area.y1;
|
||||
@@ -790,11 +804,14 @@ static void draw_letter_subpx(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_
|
||||
/*Flush the last part*/
|
||||
if(map_area.y1 != map_area.y2) {
|
||||
map_area.y2--;
|
||||
lv_blend_map(clip_area, &map_area, color_buf, mask_buf, LV_DRAW_MASK_RES_CHANGED, opa, blend_mode);
|
||||
_lv_blend_map(clip_area, &map_area, color_buf, mask_buf, LV_DRAW_MASK_RES_CHANGED, opa, blend_mode);
|
||||
}
|
||||
|
||||
lv_mem_buf_release(mask_buf);
|
||||
lv_mem_buf_release(color_buf);
|
||||
_lv_mem_buf_release(mask_buf);
|
||||
_lv_mem_buf_release(color_buf);
|
||||
#else
|
||||
LV_LOG_WARN("Can't draw sub-pixel rendered letter because LV_USE_FONT_SUBPX == 0 in lv_conf.h");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -33,8 +33,8 @@ typedef struct {
|
||||
lv_opa_t opa;
|
||||
lv_style_int_t line_space;
|
||||
lv_style_int_t letter_space;
|
||||
uint16_t sel_start;
|
||||
uint16_t sel_end;
|
||||
uint32_t sel_start;
|
||||
uint32_t sel_end;
|
||||
lv_coord_t ofs_x;
|
||||
lv_coord_t ofs_y;
|
||||
lv_bidi_dir_t bidi_dir;
|
||||
@@ -64,6 +64,8 @@ typedef struct {
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
//! @cond Doxygen_Suppress
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM void lv_draw_label_dsc_init(lv_draw_label_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
@@ -72,10 +74,14 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_label_dsc_init(lv_draw_label_dsc_t * dsc);
|
||||
* @param mask the label will be drawn only in this area
|
||||
* @param dsc pointer to draw descriptor
|
||||
* @param txt `\0` terminated text to write
|
||||
* @param hint pointer to a `lv_draw_label_hint_t` variable.
|
||||
* It is managed by the drawer to speed up the drawing of very long texts (thousands of lines).
|
||||
*/
|
||||
LV_ATTRIBUTE_FAST_MEM void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, lv_draw_label_dsc_t * dsc,
|
||||
const char * txt, lv_draw_label_hint_t * hint);
|
||||
LV_ATTRIBUTE_FAST_MEM void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask,
|
||||
const lv_draw_label_dsc_t * dsc,
|
||||
const char * txt, lv_draw_label_hint_t * hint);
|
||||
|
||||
//! @endcond
|
||||
/***********************
|
||||
* GLOBAL VARIABLES
|
||||
***********************/
|
||||
|
||||
@@ -24,12 +24,15 @@
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
LV_ATTRIBUTE_FAST_MEM static void draw_line_skew(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip,
|
||||
lv_draw_line_dsc_t * dsc);
|
||||
LV_ATTRIBUTE_FAST_MEM static void draw_line_hor(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip,
|
||||
lv_draw_line_dsc_t * dsc);
|
||||
LV_ATTRIBUTE_FAST_MEM static void draw_line_ver(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip,
|
||||
lv_draw_line_dsc_t * dsc);
|
||||
LV_ATTRIBUTE_FAST_MEM static void draw_line_skew(const lv_point_t * point1, const lv_point_t * point2,
|
||||
const lv_area_t * clip,
|
||||
const lv_draw_line_dsc_t * dsc);
|
||||
LV_ATTRIBUTE_FAST_MEM static void draw_line_hor(const lv_point_t * point1, const lv_point_t * point2,
|
||||
const lv_area_t * clip,
|
||||
const lv_draw_line_dsc_t * dsc);
|
||||
LV_ATTRIBUTE_FAST_MEM static void draw_line_ver(const lv_point_t * point1, const lv_point_t * point2,
|
||||
const lv_area_t * clip,
|
||||
const lv_draw_line_dsc_t * dsc);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@@ -45,7 +48,7 @@ LV_ATTRIBUTE_FAST_MEM static void draw_line_ver(const lv_point_t * point1, const
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM void lv_draw_line_dsc_init(lv_draw_line_dsc_t * dsc)
|
||||
{
|
||||
lv_memset_00(dsc, sizeof(lv_draw_line_dsc_t));
|
||||
_lv_memset_00(dsc, sizeof(lv_draw_line_dsc_t));
|
||||
dsc->width = 1;
|
||||
dsc->opa = LV_OPA_COVER;
|
||||
dsc->color = LV_COLOR_BLACK;
|
||||
@@ -55,12 +58,11 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_line_dsc_init(lv_draw_line_dsc_t * dsc)
|
||||
* Draw a line
|
||||
* @param point1 first point of the line
|
||||
* @param point2 second point of the line
|
||||
* @param mask the line will be drawn only on this area
|
||||
* @param style pointer to a line's style
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
* @param clip the line will be drawn only in this area
|
||||
* @param dsc pointer to an initialized `lv_draw_line_dsc_t` variable
|
||||
*/
|
||||
LV_ATTRIBUTE_FAST_MEM void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip,
|
||||
lv_draw_line_dsc_t * dsc)
|
||||
const lv_draw_line_dsc_t * dsc)
|
||||
{
|
||||
if(dsc->width == 0) return;
|
||||
if(dsc->opa <= LV_OPA_MIN) return;
|
||||
@@ -74,7 +76,7 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_line(const lv_point_t * point1, const lv_poin
|
||||
clip_line.y2 = LV_MATH_MAX(point1->y, point2->y) + dsc->width / 2;
|
||||
|
||||
bool is_common;
|
||||
is_common = lv_area_intersect(&clip_line, &clip_line, clip);
|
||||
is_common = _lv_area_intersect(&clip_line, &clip_line, clip);
|
||||
if(!is_common) return;
|
||||
|
||||
if(point1->y == point2->y) draw_line_hor(point1, point2, &clip_line, dsc);
|
||||
@@ -115,12 +117,13 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_line(const lv_point_t * point1, const lv_poin
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM static void draw_line_hor(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip,
|
||||
lv_draw_line_dsc_t * dsc)
|
||||
LV_ATTRIBUTE_FAST_MEM static void draw_line_hor(const lv_point_t * point1, const lv_point_t * point2,
|
||||
const lv_area_t * clip,
|
||||
const lv_draw_line_dsc_t * dsc)
|
||||
{
|
||||
lv_opa_t opa = dsc->opa;
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
|
||||
const lv_area_t * disp_area = &vdb->area;
|
||||
@@ -143,16 +146,16 @@ LV_ATTRIBUTE_FAST_MEM static void draw_line_hor(const lv_point_t * point1, const
|
||||
|
||||
/*If there is no mask then simply draw a rectangle*/
|
||||
if(simple_mode) {
|
||||
lv_blend_fill(clip, &draw_area,
|
||||
dsc->color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa,
|
||||
dsc->blend_mode);
|
||||
_lv_blend_fill(clip, &draw_area,
|
||||
dsc->color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa,
|
||||
dsc->blend_mode);
|
||||
}
|
||||
/*If there other mask apply it*/
|
||||
else {
|
||||
/* Get clipped fill area which is the real draw area.
|
||||
* It is always the same or inside `fill_area` */
|
||||
bool is_common;
|
||||
is_common = lv_area_intersect(&draw_area, clip, &draw_area);
|
||||
is_common = _lv_area_intersect(&draw_area, clip, &draw_area);
|
||||
if(!is_common) return;
|
||||
|
||||
/* Now `draw_area` has absolute coordinates.
|
||||
@@ -175,16 +178,16 @@ LV_ATTRIBUTE_FAST_MEM static void draw_line_hor(const lv_point_t * point1, const
|
||||
dash_start = (vdb->area.x1 + draw_area.x1) % (dsc->dash_gap + dsc->dash_width);
|
||||
}
|
||||
|
||||
lv_opa_t * mask_buf = lv_mem_buf_get(draw_area_w);
|
||||
lv_opa_t * mask_buf = _lv_mem_buf_get(draw_area_w);
|
||||
int32_t h;
|
||||
for(h = draw_area.y1; h <= draw_area.y2; h++) {
|
||||
lv_memset_ff(mask_buf, draw_area_w);
|
||||
_lv_memset_ff(mask_buf, draw_area_w);
|
||||
lv_draw_mask_res_t mask_res = lv_draw_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w);
|
||||
|
||||
if(dashed) {
|
||||
if(mask_res != LV_DRAW_MASK_RES_TRANSP) {
|
||||
lv_style_int_t dash_cnt = dash_start;
|
||||
uint32_t i;
|
||||
lv_coord_t i;
|
||||
for(i = 0; i < draw_area_w; i++, dash_cnt++) {
|
||||
if(dash_cnt <= dsc->dash_width) {
|
||||
int16_t diff = dsc->dash_width - dash_cnt;
|
||||
@@ -203,24 +206,25 @@ LV_ATTRIBUTE_FAST_MEM static void draw_line_hor(const lv_point_t * point1, const
|
||||
}
|
||||
}
|
||||
|
||||
lv_blend_fill(clip, &fill_area,
|
||||
dsc->color, mask_buf, mask_res, dsc->opa,
|
||||
dsc->blend_mode);
|
||||
_lv_blend_fill(clip, &fill_area,
|
||||
dsc->color, mask_buf, mask_res, dsc->opa,
|
||||
dsc->blend_mode);
|
||||
|
||||
fill_area.y1++;
|
||||
fill_area.y2++;
|
||||
}
|
||||
lv_mem_buf_release(mask_buf);
|
||||
_lv_mem_buf_release(mask_buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM static void draw_line_ver(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip,
|
||||
lv_draw_line_dsc_t * dsc)
|
||||
LV_ATTRIBUTE_FAST_MEM static void draw_line_ver(const lv_point_t * point1, const lv_point_t * point2,
|
||||
const lv_area_t * clip,
|
||||
const lv_draw_line_dsc_t * dsc)
|
||||
{
|
||||
lv_opa_t opa = dsc->opa;
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
|
||||
const lv_area_t * disp_area = &vdb->area;
|
||||
@@ -243,16 +247,16 @@ LV_ATTRIBUTE_FAST_MEM static void draw_line_ver(const lv_point_t * point1, const
|
||||
|
||||
/*If there is no mask then simply draw a rectangle*/
|
||||
if(simple_mode) {
|
||||
lv_blend_fill(clip, &draw_area,
|
||||
dsc->color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa,
|
||||
dsc->blend_mode);
|
||||
_lv_blend_fill(clip, &draw_area,
|
||||
dsc->color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa,
|
||||
dsc->blend_mode);
|
||||
}
|
||||
/*If there other mask apply it*/
|
||||
else {
|
||||
/* Get clipped fill area which is the real draw area.
|
||||
* It is always the same or inside `fill_area` */
|
||||
bool is_common;
|
||||
is_common = lv_area_intersect(&draw_area, clip, &draw_area);
|
||||
is_common = _lv_area_intersect(&draw_area, clip, &draw_area);
|
||||
if(!is_common) return;
|
||||
|
||||
/* Now `draw_area` has absolute coordinates.
|
||||
@@ -270,18 +274,18 @@ LV_ATTRIBUTE_FAST_MEM static void draw_line_ver(const lv_point_t * point1, const
|
||||
fill_area.y1 = draw_area.y1 + disp_area->y1;
|
||||
fill_area.y2 = fill_area.y1;
|
||||
|
||||
lv_opa_t * mask_buf = lv_mem_buf_get(draw_area_w);
|
||||
lv_opa_t * mask_buf = _lv_mem_buf_get(draw_area_w);
|
||||
|
||||
lv_style_int_t dash_start = 0;
|
||||
if(dashed) {
|
||||
dash_start = (vdb->area.x1 + draw_area.x1) % (dsc->dash_gap + dsc->dash_width);
|
||||
dash_start = (vdb->area.y1 + draw_area.y1) % (dsc->dash_gap + dsc->dash_width);
|
||||
}
|
||||
|
||||
lv_style_int_t dash_cnt = dash_start;
|
||||
|
||||
int32_t h;
|
||||
for(h = draw_area.y1; h <= draw_area.y2; h++) {
|
||||
lv_memset_ff(mask_buf, draw_area_w);
|
||||
_lv_memset_ff(mask_buf, draw_area_w);
|
||||
lv_draw_mask_res_t mask_res = lv_draw_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w);
|
||||
|
||||
if(dashed) {
|
||||
@@ -297,20 +301,21 @@ LV_ATTRIBUTE_FAST_MEM static void draw_line_ver(const lv_point_t * point1, const
|
||||
dash_cnt ++;
|
||||
}
|
||||
|
||||
lv_blend_fill(clip, &fill_area,
|
||||
dsc->color, mask_buf, mask_res, dsc->opa,
|
||||
LV_BLEND_MODE_NORMAL);
|
||||
_lv_blend_fill(clip, &fill_area,
|
||||
dsc->color, mask_buf, mask_res, dsc->opa,
|
||||
LV_BLEND_MODE_NORMAL);
|
||||
|
||||
fill_area.y1++;
|
||||
fill_area.y2++;
|
||||
}
|
||||
lv_mem_buf_release(mask_buf);
|
||||
_lv_mem_buf_release(mask_buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM static void draw_line_skew(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip,
|
||||
lv_draw_line_dsc_t * dsc)
|
||||
LV_ATTRIBUTE_FAST_MEM static void draw_line_skew(const lv_point_t * point1, const lv_point_t * point2,
|
||||
const lv_area_t * clip,
|
||||
const lv_draw_line_dsc_t * dsc)
|
||||
{
|
||||
/*Keep the great y in p1*/
|
||||
lv_point_t p1;
|
||||
@@ -358,7 +363,7 @@ LV_ATTRIBUTE_FAST_MEM static void draw_line_skew(const lv_point_t * point1, cons
|
||||
/* Get the union of `coords` and `clip`*/
|
||||
/* `clip` is already truncated to the `vdb` size
|
||||
* in 'lv_refr_area' function */
|
||||
bool is_common = lv_area_intersect(&draw_area, &draw_area, clip);
|
||||
bool is_common = _lv_area_intersect(&draw_area, &draw_area, clip);
|
||||
if(is_common == false) return;
|
||||
|
||||
lv_draw_mask_line_param_t mask_left_param;
|
||||
@@ -401,7 +406,7 @@ LV_ATTRIBUTE_FAST_MEM static void draw_line_skew(const lv_point_t * point1, cons
|
||||
mask_bottom_id = lv_draw_mask_add(&mask_bottom_param, NULL);
|
||||
}
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
|
||||
const lv_area_t * disp_area = &vdb->area;
|
||||
@@ -420,7 +425,7 @@ LV_ATTRIBUTE_FAST_MEM static void draw_line_skew(const lv_point_t * point1, cons
|
||||
/*Draw the background line by line*/
|
||||
int32_t h;
|
||||
size_t mask_buf_size = LV_MATH_MIN(lv_area_get_size(&draw_area), LV_HOR_RES_MAX);
|
||||
lv_opa_t * mask_buf = lv_mem_buf_get(mask_buf_size);
|
||||
lv_opa_t * mask_buf = _lv_mem_buf_get(mask_buf_size);
|
||||
|
||||
lv_area_t fill_area;
|
||||
fill_area.x1 = draw_area.x1 + disp_area->x1;
|
||||
@@ -432,13 +437,13 @@ LV_ATTRIBUTE_FAST_MEM static void draw_line_skew(const lv_point_t * point1, cons
|
||||
|
||||
uint32_t mask_p = 0;
|
||||
|
||||
lv_memset_ff(mask_buf, mask_buf_size);
|
||||
_lv_memset_ff(mask_buf, mask_buf_size);
|
||||
/*Fill the first row with 'color'*/
|
||||
for(h = draw_area.y1 + disp_area->y1; h <= draw_area.y2 + disp_area->y1; h++) {
|
||||
|
||||
lv_draw_mask_res_t mask_res = lv_draw_mask_apply(&mask_buf[mask_p], x, h, draw_area_w);
|
||||
if(mask_res == LV_DRAW_MASK_RES_TRANSP) {
|
||||
lv_memset_00(&mask_buf[mask_p], draw_area_w);
|
||||
_lv_memset_00(&mask_buf[mask_p], draw_area_w);
|
||||
}
|
||||
|
||||
mask_p += draw_area_w;
|
||||
@@ -446,27 +451,27 @@ LV_ATTRIBUTE_FAST_MEM static void draw_line_skew(const lv_point_t * point1, cons
|
||||
fill_area.y2 ++;
|
||||
}
|
||||
else {
|
||||
lv_blend_fill(&fill_area, clip,
|
||||
dsc->color, mask_buf, LV_DRAW_MASK_RES_CHANGED, dsc->opa,
|
||||
dsc->blend_mode);
|
||||
_lv_blend_fill(&fill_area, clip,
|
||||
dsc->color, mask_buf, LV_DRAW_MASK_RES_CHANGED, dsc->opa,
|
||||
dsc->blend_mode);
|
||||
|
||||
fill_area.y1 = fill_area.y2 + 1;
|
||||
fill_area.y2 = fill_area.y1;
|
||||
mask_p = 0;
|
||||
lv_memset_ff(mask_buf, mask_buf_size);
|
||||
_lv_memset_ff(mask_buf, mask_buf_size);
|
||||
}
|
||||
}
|
||||
|
||||
/*Flush the last part*/
|
||||
if(fill_area.y1 != fill_area.y2) {
|
||||
fill_area.y2--;
|
||||
lv_blend_fill( &fill_area, clip,
|
||||
dsc->color, mask_buf, LV_DRAW_MASK_RES_CHANGED, dsc->opa,
|
||||
dsc->blend_mode);
|
||||
_lv_blend_fill(&fill_area, clip,
|
||||
dsc->color, mask_buf, LV_DRAW_MASK_RES_CHANGED, dsc->opa,
|
||||
dsc->blend_mode);
|
||||
|
||||
}
|
||||
|
||||
lv_mem_buf_release(mask_buf);
|
||||
_lv_mem_buf_release(mask_buf);
|
||||
|
||||
lv_draw_mask_remove_id(mask_left_id);
|
||||
lv_draw_mask_remove_id(mask_right_id);
|
||||
|
||||
@@ -38,19 +38,22 @@ typedef struct {
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
//! @cond Doxygen_Suppress
|
||||
/**
|
||||
* Draw a line
|
||||
* @param point1 first point of the line
|
||||
* @param point2 second point of the line
|
||||
* @param mask the line will be drawn only on this area
|
||||
* @param style pointer to a line's style
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
* @param clip the line will be drawn only in this area
|
||||
* @param dsc pointer to an initialized `lv_draw_line_dsc_t` variable
|
||||
*/
|
||||
LV_ATTRIBUTE_FAST_MEM void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * mask,
|
||||
lv_draw_line_dsc_t * dsc);
|
||||
LV_ATTRIBUTE_FAST_MEM void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip,
|
||||
const lv_draw_line_dsc_t * dsc);
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM void lv_draw_line_dsc_init(lv_draw_line_dsc_t * dsc);
|
||||
|
||||
|
||||
//! @endcond
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
@@ -13,39 +13,46 @@
|
||||
#include "lv_draw_mask.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
#include "../lv_misc/lv_log.h"
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "../lv_misc/lv_debug.h"
|
||||
#include "../lv_misc/lv_gc.h"
|
||||
|
||||
#if defined(LV_GC_INCLUDE)
|
||||
#include LV_GC_INCLUDE
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_MASK_MAX_NUM 16
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef struct {
|
||||
void * param;
|
||||
void * custom_id;
|
||||
} lv_mask_saved_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_line(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len,
|
||||
lv_draw_mask_line_param_t * param);
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_radius(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len,
|
||||
lv_draw_mask_radius_param_t * param);
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_angle(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len,
|
||||
lv_draw_mask_angle_param_t * param);
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_fade(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len,
|
||||
lv_draw_mask_fade_param_t * param);
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_map(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len,
|
||||
lv_draw_mask_map_param_t * param);
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_line(lv_opa_t * mask_buf, lv_coord_t abs_x,
|
||||
lv_coord_t abs_y, lv_coord_t len,
|
||||
lv_draw_mask_line_param_t * param);
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_radius(lv_opa_t * mask_buf, lv_coord_t abs_x,
|
||||
lv_coord_t abs_y, lv_coord_t len,
|
||||
lv_draw_mask_radius_param_t * param);
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_angle(lv_opa_t * mask_buf, lv_coord_t abs_x,
|
||||
lv_coord_t abs_y, lv_coord_t len,
|
||||
lv_draw_mask_angle_param_t * param);
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_fade(lv_opa_t * mask_buf, lv_coord_t abs_x,
|
||||
lv_coord_t abs_y, lv_coord_t len,
|
||||
lv_draw_mask_fade_param_t * param);
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_map(lv_opa_t * mask_buf, lv_coord_t abs_x,
|
||||
lv_coord_t abs_y, lv_coord_t len,
|
||||
lv_draw_mask_map_param_t * param);
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t line_mask_flat(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len,
|
||||
lv_draw_mask_line_param_t * p);
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t line_mask_steep(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len,
|
||||
lv_draw_mask_line_param_t * p);
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t line_mask_flat(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y,
|
||||
lv_coord_t len,
|
||||
lv_draw_mask_line_param_t * p);
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t line_mask_steep(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y,
|
||||
lv_coord_t len,
|
||||
lv_draw_mask_line_param_t * p);
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM static inline lv_opa_t mask_mix(lv_opa_t mask_act, lv_opa_t mask_new);
|
||||
LV_ATTRIBUTE_FAST_MEM static inline void sqrt_approx(lv_sqrt_res_t * q, lv_sqrt_res_t * ref, uint32_t x);
|
||||
@@ -53,7 +60,6 @@ LV_ATTRIBUTE_FAST_MEM static inline void sqrt_approx(lv_sqrt_res_t * q, lv_sqrt_
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_mask_saved_t mask_list[LV_MASK_MAX_NUM];
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
@@ -73,38 +79,39 @@ int16_t lv_draw_mask_add(void * param, void * custom_id)
|
||||
{
|
||||
/*Look for a free entry*/
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MASK_MAX_NUM; i++) {
|
||||
if(mask_list[i].param == NULL) break;
|
||||
for(i = 0; i < _LV_MASK_MAX_NUM; i++) {
|
||||
if(LV_GC_ROOT(_lv_draw_mask_list[i]).param == NULL) break;
|
||||
}
|
||||
|
||||
if(i >= LV_MASK_MAX_NUM) {
|
||||
if(i >= _LV_MASK_MAX_NUM) {
|
||||
LV_LOG_WARN("lv_mask_add: no place to add the mask");
|
||||
return LV_MASK_ID_INV;
|
||||
}
|
||||
|
||||
mask_list[i].param = param;
|
||||
mask_list[i].custom_id = custom_id;
|
||||
LV_GC_ROOT(_lv_draw_mask_list[i]).param = param;
|
||||
LV_GC_ROOT(_lv_draw_mask_list[i]).custom_id = custom_id;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the added buffers on a line. Used internally by the library's drawing routins.
|
||||
* Apply the added buffers on a line. Used internally by the library's drawing routines.
|
||||
* @param mask_buf store the result mask here. Has to be `len` byte long. Should be initialized with `0xFF`.
|
||||
* @param abs_x absolute X coordinate where the line to calculate start
|
||||
* @param abs_y absolute Y coordinate where the line to calculate start
|
||||
* @param len length of the line to calculate (in pixel count)
|
||||
* @return Oneof these values:
|
||||
* @return One of these values:
|
||||
* - `LV_DRAW_MASK_RES_FULL_TRANSP`: the whole line is transparent. `mask_buf` is not set to zero
|
||||
* - `LV_DRAW_MASK_RES_FULL_COVER`: the whole line is fully visible. `mask_buf` is unchanged
|
||||
* - `LV_DRAW_MASK_RES_CHANGED`: `mask_buf` has changed, it shows the desired opacity of each pixel in the given line
|
||||
*/
|
||||
LV_ATTRIBUTE_FAST_MEM lv_draw_mask_res_t lv_draw_mask_apply(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len)
|
||||
LV_ATTRIBUTE_FAST_MEM lv_draw_mask_res_t lv_draw_mask_apply(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y,
|
||||
lv_coord_t len)
|
||||
{
|
||||
bool changed = false;
|
||||
lv_draw_mask_common_dsc_t * dsc;
|
||||
|
||||
lv_mask_saved_t * m = mask_list;
|
||||
_lv_draw_mask_saved_t * m = LV_GC_ROOT(_lv_draw_mask_list);
|
||||
|
||||
while(m->param) {
|
||||
dsc = m->param;
|
||||
@@ -130,9 +137,9 @@ void * lv_draw_mask_remove_id(int16_t id)
|
||||
void * p = NULL;
|
||||
|
||||
if(id != LV_MASK_ID_INV) {
|
||||
p = mask_list[id].param;
|
||||
mask_list[id].param = NULL;
|
||||
mask_list[id].custom_id = NULL;
|
||||
p = LV_GC_ROOT(_lv_draw_mask_list[id]).param;
|
||||
LV_GC_ROOT(_lv_draw_mask_list[id]).param = NULL;
|
||||
LV_GC_ROOT(_lv_draw_mask_list[id]).custom_id = NULL;
|
||||
}
|
||||
|
||||
return p;
|
||||
@@ -148,11 +155,11 @@ void * lv_draw_mask_remove_custom(void * custom_id)
|
||||
{
|
||||
void * p = NULL;
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MASK_MAX_NUM; i++) {
|
||||
if(mask_list[i].custom_id == custom_id) {
|
||||
p = mask_list[i].param;
|
||||
mask_list[i].param = NULL;
|
||||
mask_list[i].custom_id = NULL;
|
||||
for(i = 0; i < _LV_MASK_MAX_NUM; i++) {
|
||||
if(LV_GC_ROOT(_lv_draw_mask_list[i]).custom_id == custom_id) {
|
||||
p = LV_GC_ROOT(_lv_draw_mask_list[i]).param;
|
||||
LV_GC_ROOT(_lv_draw_mask_list[i]).param = NULL;
|
||||
LV_GC_ROOT(_lv_draw_mask_list[i]).custom_id = NULL;
|
||||
}
|
||||
}
|
||||
return p;
|
||||
@@ -166,8 +173,8 @@ LV_ATTRIBUTE_FAST_MEM uint8_t lv_draw_mask_get_cnt(void)
|
||||
{
|
||||
uint8_t cnt = 0;
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MASK_MAX_NUM; i++) {
|
||||
if(mask_list[i].param) cnt++;
|
||||
for(i = 0; i < _LV_MASK_MAX_NUM; i++) {
|
||||
if(LV_GC_ROOT(_lv_draw_mask_list[i]).param) cnt++;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
@@ -186,7 +193,7 @@ LV_ATTRIBUTE_FAST_MEM uint8_t lv_draw_mask_get_cnt(void)
|
||||
void lv_draw_mask_line_points_init(lv_draw_mask_line_param_t * param, lv_coord_t p1x, lv_coord_t p1y, lv_coord_t p2x,
|
||||
lv_coord_t p2y, lv_draw_mask_line_side_t side)
|
||||
{
|
||||
lv_memset_00(param, sizeof(lv_draw_mask_line_param_t));
|
||||
_lv_memset_00(param, sizeof(lv_draw_mask_line_param_t));
|
||||
|
||||
if(p1y > p2y) {
|
||||
lv_coord_t t;
|
||||
@@ -265,8 +272,8 @@ void lv_draw_mask_line_points_init(lv_draw_mask_line_param_t * param, lv_coord_t
|
||||
/**
|
||||
*Initialize a line mask from a point and an angle.
|
||||
* @param param pointer to a `lv_draw_mask_param_t` to initialize
|
||||
* @param px X coordiante of a point of the line
|
||||
* @param py X coordiante of a point of the line
|
||||
* @param px X coordinate of a point of the line
|
||||
* @param py X coordinate of a point of the line
|
||||
* @param angle right 0 deg, bottom: 90
|
||||
* @param side and element of `lv_draw_mask_line_side_t` to describe which side to keep.
|
||||
* With `LV_DRAW_MASK_LINE_SIDE_LEFT/RIGHT` and horizontal line all pixels are kept
|
||||
@@ -285,8 +292,8 @@ void lv_draw_mask_line_angle_init(lv_draw_mask_line_param_t * param, lv_coord_t
|
||||
int32_t p2x;
|
||||
int32_t p2y;
|
||||
|
||||
p2x = (lv_trigo_sin(angle + 90) >> 5) + p1x;
|
||||
p2y = (lv_trigo_sin(angle) >> 5) + py;
|
||||
p2x = (_lv_trigo_sin(angle + 90) >> 5) + p1x;
|
||||
p2y = (_lv_trigo_sin(angle) >> 5) + py;
|
||||
|
||||
lv_draw_mask_line_points_init(param, p1x, py, p2x, p2y, side);
|
||||
}
|
||||
@@ -363,7 +370,7 @@ void lv_draw_mask_angle_init(lv_draw_mask_angle_param_t * param, lv_coord_t vert
|
||||
* @param param param pointer to a `lv_draw_mask_param_t` to initialize
|
||||
* @param rect coordinates of the rectangle to affect (absolute coordinates)
|
||||
* @param radius radius of the rectangle
|
||||
* @param inv: true: keep the pixels inside teh rectangle; keep teh pixels outside of the rectangle
|
||||
* @param inv: true: keep the pixels inside the rectangle; keep the pixels outside of the rectangle
|
||||
*/
|
||||
void lv_draw_mask_radius_init(lv_draw_mask_radius_param_t * param, const lv_area_t * rect, lv_coord_t radius, bool inv)
|
||||
{
|
||||
@@ -425,8 +432,9 @@ void lv_draw_mask_map_init(lv_draw_mask_map_param_t * param, const lv_area_t * c
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_line(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len,
|
||||
lv_draw_mask_line_param_t * p)
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_line(lv_opa_t * mask_buf, lv_coord_t abs_x,
|
||||
lv_coord_t abs_y, lv_coord_t len,
|
||||
lv_draw_mask_line_param_t * p)
|
||||
{
|
||||
/*Make to points relative to the vertex*/
|
||||
abs_y -= p->origo.y;
|
||||
@@ -456,7 +464,7 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_line(lv_opa_t * mas
|
||||
else {
|
||||
int32_t k = - abs_x;
|
||||
if(k < 0) return LV_DRAW_MASK_RES_TRANSP;
|
||||
if(k >= 0 && k < len) lv_memset_00(&mask_buf[k], len - k);
|
||||
if(k >= 0 && k < len) _lv_memset_00(&mask_buf[k], len - k);
|
||||
return LV_DRAW_MASK_RES_CHANGED;
|
||||
}
|
||||
}
|
||||
@@ -466,7 +474,7 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_line(lv_opa_t * mas
|
||||
int32_t k = - abs_x;
|
||||
if(k < 0) k = 0;
|
||||
if(k >= len) return LV_DRAW_MASK_RES_TRANSP;
|
||||
else if(k >= 0 && k < len) lv_memset_00(&mask_buf[0], k);
|
||||
else if(k >= 0 && k < len) _lv_memset_00(&mask_buf[0], k);
|
||||
return LV_DRAW_MASK_RES_CHANGED;
|
||||
}
|
||||
}
|
||||
@@ -484,8 +492,9 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_line(lv_opa_t * mas
|
||||
return res;
|
||||
}
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t line_mask_flat(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len,
|
||||
lv_draw_mask_line_param_t * p)
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t line_mask_flat(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y,
|
||||
lv_coord_t len,
|
||||
lv_draw_mask_line_param_t * p)
|
||||
{
|
||||
int32_t y_at_x;
|
||||
y_at_x = (int32_t)((int32_t)p->yx_steep * abs_x) >> 10;
|
||||
@@ -584,7 +593,7 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t line_mask_flat(lv_opa_t * mask_b
|
||||
return LV_DRAW_MASK_RES_TRANSP;
|
||||
}
|
||||
if(k >= 0) {
|
||||
lv_memset_00(&mask_buf[0], k);
|
||||
_lv_memset_00(&mask_buf[0], k);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -593,15 +602,16 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t line_mask_flat(lv_opa_t * mask_b
|
||||
return LV_DRAW_MASK_RES_TRANSP;
|
||||
}
|
||||
if(k <= len) {
|
||||
lv_memset_00(&mask_buf[k], len - k);
|
||||
_lv_memset_00(&mask_buf[k], len - k);
|
||||
}
|
||||
}
|
||||
|
||||
return LV_DRAW_MASK_RES_CHANGED;
|
||||
}
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t line_mask_steep(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len,
|
||||
lv_draw_mask_line_param_t * p)
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t line_mask_steep(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y,
|
||||
lv_coord_t len,
|
||||
lv_draw_mask_line_param_t * p)
|
||||
{
|
||||
int32_t k;
|
||||
int32_t x_at_y;
|
||||
@@ -662,13 +672,13 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t line_mask_steep(lv_opa_t * mask_
|
||||
if(k >= len) {
|
||||
return LV_DRAW_MASK_RES_TRANSP;
|
||||
}
|
||||
if(k >= 0) lv_memset_00(&mask_buf[0], k);
|
||||
if(k >= 0) _lv_memset_00(&mask_buf[0], k);
|
||||
|
||||
}
|
||||
else {
|
||||
if(k > len) k = len;
|
||||
if(k == 0) return LV_DRAW_MASK_RES_TRANSP;
|
||||
else if(k > 0) lv_memset_00(&mask_buf[k], len - k);
|
||||
else if(k > 0) _lv_memset_00(&mask_buf[k], len - k);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -697,12 +707,12 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t line_mask_steep(lv_opa_t * mask_
|
||||
k = xsi - abs_x - 1;
|
||||
|
||||
if(k > len) k = len;
|
||||
else if(k > 0) lv_memset_00(&mask_buf[0], k);
|
||||
else if(k > 0) _lv_memset_00(&mask_buf[0], k);
|
||||
|
||||
}
|
||||
else {
|
||||
if(k > len) return LV_DRAW_MASK_RES_FULL_COVER;
|
||||
if(k >= 0) lv_memset_00(&mask_buf[k], len - k);
|
||||
if(k >= 0) _lv_memset_00(&mask_buf[k], len - k);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -727,13 +737,13 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t line_mask_steep(lv_opa_t * mask_
|
||||
if(p->inv) {
|
||||
k = xsi - abs_x;
|
||||
if(k > len) return LV_DRAW_MASK_RES_TRANSP;
|
||||
if(k >= 0) lv_memset_00(&mask_buf[0], k);
|
||||
if(k >= 0) _lv_memset_00(&mask_buf[0], k);
|
||||
|
||||
}
|
||||
else {
|
||||
if(k > len) k = len;
|
||||
if(k == 0) return LV_DRAW_MASK_RES_TRANSP;
|
||||
else if(k > 0) lv_memset_00(&mask_buf[k], len - k);
|
||||
else if(k > 0) _lv_memset_00(&mask_buf[k], len - k);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -742,8 +752,9 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t line_mask_steep(lv_opa_t * mask_
|
||||
}
|
||||
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_angle(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len,
|
||||
lv_draw_mask_angle_param_t * p)
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_angle(lv_opa_t * mask_buf, lv_coord_t abs_x,
|
||||
lv_coord_t abs_y, lv_coord_t len,
|
||||
lv_draw_mask_angle_param_t * p)
|
||||
{
|
||||
int32_t rel_y = abs_y - p->cfg.vertex_p.y;
|
||||
int32_t rel_x = abs_x - p->cfg.vertex_p.x;
|
||||
@@ -782,7 +793,7 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_angle(lv_opa_t * ma
|
||||
if(tmp > 0) {
|
||||
res1 = lv_draw_mask_line(&mask_buf[0], abs_x, abs_y, tmp, &p->start_line);
|
||||
if(res1 == LV_DRAW_MASK_RES_TRANSP) {
|
||||
lv_memset_00(&mask_buf[0], tmp);
|
||||
_lv_memset_00(&mask_buf[0], tmp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -790,7 +801,7 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_angle(lv_opa_t * ma
|
||||
if(tmp < 0) tmp = 0;
|
||||
res2 = lv_draw_mask_line(&mask_buf[tmp], abs_x + tmp, abs_y, len - tmp, &p->end_line);
|
||||
if(res2 == LV_DRAW_MASK_RES_TRANSP) {
|
||||
lv_memset_00(&mask_buf[tmp], len - tmp);
|
||||
_lv_memset_00(&mask_buf[tmp], len - tmp);
|
||||
}
|
||||
if(res1 == res2) return res1;
|
||||
else return LV_DRAW_MASK_RES_CHANGED;
|
||||
@@ -824,7 +835,7 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_angle(lv_opa_t * ma
|
||||
if(tmp > 0) {
|
||||
res1 = lv_draw_mask_line(&mask_buf[0], abs_x, abs_y, tmp, (lv_draw_mask_line_param_t *)&p->end_line);
|
||||
if(res1 == LV_DRAW_MASK_RES_TRANSP) {
|
||||
lv_memset_00(&mask_buf[0], tmp);
|
||||
_lv_memset_00(&mask_buf[0], tmp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -832,7 +843,7 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_angle(lv_opa_t * ma
|
||||
if(tmp < 0) tmp = 0;
|
||||
res2 = lv_draw_mask_line(&mask_buf[tmp], abs_x + tmp, abs_y, len - tmp, (lv_draw_mask_line_param_t *)&p->start_line);
|
||||
if(res2 == LV_DRAW_MASK_RES_TRANSP) {
|
||||
lv_memset_00(&mask_buf[tmp], len - tmp);
|
||||
_lv_memset_00(&mask_buf[tmp], len - tmp);
|
||||
}
|
||||
if(res1 == res2) return res1;
|
||||
else return LV_DRAW_MASK_RES_CHANGED;
|
||||
@@ -881,8 +892,9 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_angle(lv_opa_t * ma
|
||||
}
|
||||
}
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_radius(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len,
|
||||
lv_draw_mask_radius_param_t * p)
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_radius(lv_opa_t * mask_buf, lv_coord_t abs_x,
|
||||
lv_coord_t abs_y, lv_coord_t len,
|
||||
lv_draw_mask_radius_param_t * p)
|
||||
{
|
||||
bool outer = p->cfg.outer;
|
||||
int32_t radius = p->cfg.radius;
|
||||
@@ -890,7 +902,7 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_radius(lv_opa_t * m
|
||||
lv_area_copy(&rect, &p->cfg.rect);
|
||||
|
||||
if(outer == false) {
|
||||
if(abs_y < rect.y1 || abs_y >rect.y2) {
|
||||
if(abs_y < rect.y1 || abs_y > rect.y2) {
|
||||
return LV_DRAW_MASK_RES_TRANSP;
|
||||
}
|
||||
}
|
||||
@@ -907,13 +919,13 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_radius(lv_opa_t * m
|
||||
int32_t last = rect.x1 - abs_x;
|
||||
if(last > len) return LV_DRAW_MASK_RES_TRANSP;
|
||||
if(last >= 0) {
|
||||
lv_memset_00(&mask_buf[0], last);
|
||||
_lv_memset_00(&mask_buf[0], last);
|
||||
}
|
||||
|
||||
int32_t first = rect.x2 - abs_x + 1;
|
||||
if(first <= 0) return LV_DRAW_MASK_RES_TRANSP;
|
||||
else if(first < len) {
|
||||
lv_memset_00(&mask_buf[first], len - first);
|
||||
_lv_memset_00(&mask_buf[first], len - first);
|
||||
}
|
||||
if(last == 0 && first == len) return LV_DRAW_MASK_RES_FULL_COVER;
|
||||
else return LV_DRAW_MASK_RES_CHANGED;
|
||||
@@ -925,7 +937,7 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_radius(lv_opa_t * m
|
||||
int32_t last = rect.x2 - abs_x - first + 1;
|
||||
if(first + last > len) last = len - first;
|
||||
if(last >= 0) {
|
||||
lv_memset_00(&mask_buf[first], last);
|
||||
_lv_memset_00(&mask_buf[first], last);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -961,11 +973,12 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_radius(lv_opa_t * m
|
||||
if(y == p->y_prev) {
|
||||
x0.f = p->y_prev_x.f;
|
||||
x0.i = p->y_prev_x.i;
|
||||
} else {
|
||||
lv_sqrt(r2 - (y * y), &x0, sqrt_mask);
|
||||
}
|
||||
lv_sqrt(r2 - ((y - 1) * (y - 1)), &x1, sqrt_mask);
|
||||
p->y_prev = y-1;
|
||||
else {
|
||||
_lv_sqrt(r2 - (y * y), &x0, sqrt_mask);
|
||||
}
|
||||
_lv_sqrt(r2 - ((y - 1) * (y - 1)), &x1, sqrt_mask);
|
||||
p->y_prev = y - 1;
|
||||
p->y_prev_x.f = x1.f;
|
||||
p->y_prev_x.i = x1.i;
|
||||
}
|
||||
@@ -978,11 +991,12 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_radius(lv_opa_t * m
|
||||
if((y - 1) == p->y_prev) {
|
||||
x1.f = p->y_prev_x.f;
|
||||
x1.i = p->y_prev_x.i;
|
||||
} else {
|
||||
lv_sqrt(r2 - ((y - 1) * (y - 1)), &x1, sqrt_mask);
|
||||
}
|
||||
else {
|
||||
_lv_sqrt(r2 - ((y - 1) * (y - 1)), &x1, sqrt_mask);
|
||||
}
|
||||
|
||||
lv_sqrt(r2 - (y * y), &x0, sqrt_mask);
|
||||
_lv_sqrt(r2 - (y * y), &x0, sqrt_mask);
|
||||
p->y_prev = y;
|
||||
p->y_prev_x.f = x0.f;
|
||||
p->y_prev_x.i = x0.i;
|
||||
@@ -1021,13 +1035,13 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_radius(lv_opa_t * m
|
||||
return LV_DRAW_MASK_RES_TRANSP;
|
||||
}
|
||||
if(kl >= 0) {
|
||||
lv_memset_00(&mask_buf[0], kl);
|
||||
_lv_memset_00(&mask_buf[0], kl);
|
||||
}
|
||||
if(kr < 0) {
|
||||
return LV_DRAW_MASK_RES_TRANSP;
|
||||
}
|
||||
if(kr <= len) {
|
||||
lv_memset_00(&mask_buf[kr], len - kr);
|
||||
_lv_memset_00(&mask_buf[kr], len - kr);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1038,7 +1052,7 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_radius(lv_opa_t * m
|
||||
int32_t len_tmp = kr - first;
|
||||
if(len_tmp + first > len) len_tmp = len - first;
|
||||
if(first < len && len_tmp >= 0) {
|
||||
lv_memset_00(&mask_buf[first], len_tmp);
|
||||
_lv_memset_00(&mask_buf[first], len_tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1055,7 +1069,7 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_radius(lv_opa_t * m
|
||||
int32_t len_tmp = kr - first;
|
||||
if(len_tmp + first > len) len_tmp = len - first;
|
||||
if(first < len && len_tmp >= 0) {
|
||||
lv_memset_00(&mask_buf[first], len_tmp);
|
||||
_lv_memset_00(&mask_buf[first], len_tmp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1064,7 +1078,7 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_radius(lv_opa_t * m
|
||||
lv_sqrt_res_t y_prev;
|
||||
lv_sqrt_res_t y_next;
|
||||
|
||||
lv_sqrt(r2 - (x0.i * x0.i), &y_prev, sqrt_mask);
|
||||
_lv_sqrt(r2 - (x0.i * x0.i), &y_prev, sqrt_mask);
|
||||
|
||||
if(y_prev.f == 0) {
|
||||
y_prev.i--;
|
||||
@@ -1073,7 +1087,7 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_radius(lv_opa_t * m
|
||||
|
||||
/*The first y intersection is special as it might be in the previous line*/
|
||||
if(y_prev.i >= y) {
|
||||
lv_sqrt(r2 - (i * i), &y_next, sqrt_mask);
|
||||
_lv_sqrt(r2 - (i * i), &y_next, sqrt_mask);
|
||||
m = 255 - (((255 - x0.f) * (255 - y_next.f)) >> 9);
|
||||
|
||||
if(outer) m = 255 - m;
|
||||
@@ -1116,12 +1130,12 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_radius(lv_opa_t * m
|
||||
if(kl > len) {
|
||||
return LV_DRAW_MASK_RES_TRANSP;
|
||||
}
|
||||
if(kl >= 0) lv_memset_00(&mask_buf[0], kl);
|
||||
if(kl >= 0) _lv_memset_00(&mask_buf[0], kl);
|
||||
|
||||
if(kr < 0) {
|
||||
return LV_DRAW_MASK_RES_TRANSP;
|
||||
}
|
||||
if(kr < len) lv_memset_00(&mask_buf[kr], len - kr);
|
||||
if(kr < len) _lv_memset_00(&mask_buf[kr], len - kr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1130,8 +1144,9 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_radius(lv_opa_t * m
|
||||
}
|
||||
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_fade(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len,
|
||||
lv_draw_mask_fade_param_t * p)
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_fade(lv_opa_t * mask_buf, lv_coord_t abs_x,
|
||||
lv_coord_t abs_y, lv_coord_t len,
|
||||
lv_draw_mask_fade_param_t * p)
|
||||
{
|
||||
if(abs_y < p->cfg.coords.y1) return LV_DRAW_MASK_RES_FULL_COVER;
|
||||
if(abs_y > p->cfg.coords.y2) return LV_DRAW_MASK_RES_FULL_COVER;
|
||||
@@ -1175,8 +1190,9 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_fade(lv_opa_t * mas
|
||||
}
|
||||
}
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_map(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len,
|
||||
lv_draw_mask_map_param_t * p)
|
||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_map(lv_opa_t * mask_buf, lv_coord_t abs_x,
|
||||
lv_coord_t abs_y, lv_coord_t len,
|
||||
lv_draw_mask_map_param_t * p)
|
||||
{
|
||||
/*Handle out of the mask cases*/
|
||||
if(abs_y < p->cfg.coords.y1) return LV_DRAW_MASK_RES_FULL_COVER;
|
||||
@@ -1229,7 +1245,7 @@ LV_ATTRIBUTE_FAST_MEM static inline void sqrt_approx(lv_sqrt_res_t * q, lv_sqrt_
|
||||
x = x << 8; /*Upscale for extra precision*/
|
||||
|
||||
uint32_t raw = (ref->i << 4) + (ref->f >> 4);
|
||||
uint32_t raw2 = raw*raw;
|
||||
uint32_t raw2 = raw * raw;
|
||||
|
||||
int32_t d = x - raw2;
|
||||
d = (int32_t)d / (int32_t)(2 * raw) + raw;
|
||||
|
||||
@@ -21,6 +21,7 @@ extern "C" {
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_MASK_ID_INV (-1)
|
||||
#define _LV_MASK_MAX_NUM 16
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@@ -57,8 +58,9 @@ enum {
|
||||
* A common callback type for every mask type.
|
||||
* Used internally by the library.
|
||||
*/
|
||||
typedef lv_draw_mask_res_t (*lv_draw_mask_xcb_t)(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len,
|
||||
void * p);
|
||||
typedef lv_draw_mask_res_t (*lv_draw_mask_xcb_t)(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y,
|
||||
lv_coord_t len,
|
||||
void * p);
|
||||
|
||||
typedef uint8_t lv_draw_mask_line_side_t;
|
||||
|
||||
@@ -160,6 +162,13 @@ typedef struct _lv_draw_mask_map_param_t {
|
||||
} cfg;
|
||||
} lv_draw_mask_map_param_t;
|
||||
|
||||
typedef struct {
|
||||
void * param;
|
||||
void * custom_id;
|
||||
} _lv_draw_mask_saved_t;
|
||||
|
||||
typedef _lv_draw_mask_saved_t _lv_draw_mask_saved_arr_t[_LV_MASK_MAX_NUM];
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
@@ -172,18 +181,25 @@ typedef struct _lv_draw_mask_map_param_t {
|
||||
*/
|
||||
int16_t lv_draw_mask_add(void * param, void * custom_id);
|
||||
|
||||
|
||||
//! @cond Doxygen_Suppress
|
||||
|
||||
/**
|
||||
* Apply the added buffers on a line. Used internally by the library's drawing routines.
|
||||
* @param mask_buf store the result mask here. Has to be `len` byte long. Should be initialized with `0xFF`.
|
||||
* @param abs_x absolute X coordinate where the line to calculate start
|
||||
* @param abs_y absolute Y coordinate where the line to calculate start
|
||||
* @param len length of the line to calculate (in pixel count)
|
||||
* @return Oneof these values:
|
||||
* @return One of these values:
|
||||
* - `LV_DRAW_MASK_RES_FULL_TRANSP`: the whole line is transparent. `mask_buf` is not set to zero
|
||||
* - `LV_DRAW_MASK_RES_FULL_COVER`: the whole line is fully visible. `mask_buf` is unchanged
|
||||
* - `LV_DRAW_MASK_RES_CHANGED`: `mask_buf` has changed, it shows the desired opacity of each pixel in the given line
|
||||
*/
|
||||
LV_ATTRIBUTE_FAST_MEM lv_draw_mask_res_t lv_draw_mask_apply(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len);
|
||||
LV_ATTRIBUTE_FAST_MEM lv_draw_mask_res_t lv_draw_mask_apply(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y,
|
||||
lv_coord_t len);
|
||||
|
||||
|
||||
//! @endcond
|
||||
|
||||
/**
|
||||
* Remove a mask with a given ID
|
||||
@@ -201,12 +217,17 @@ void * lv_draw_mask_remove_id(int16_t id);
|
||||
*/
|
||||
void * lv_draw_mask_remove_custom(void * custom_id);
|
||||
|
||||
//! @cond Doxygen_Suppress
|
||||
|
||||
/**
|
||||
* Count the currently added masks
|
||||
* @return number of active masks
|
||||
*/
|
||||
LV_ATTRIBUTE_FAST_MEM uint8_t lv_draw_mask_get_cnt(void);
|
||||
|
||||
|
||||
//! @endcond
|
||||
|
||||
/**
|
||||
*Initialize a line mask from two points.
|
||||
* @param param pointer to a `lv_draw_mask_param_t` to initialize
|
||||
@@ -224,8 +245,8 @@ void lv_draw_mask_line_points_init(lv_draw_mask_line_param_t * param, lv_coord_t
|
||||
/**
|
||||
*Initialize a line mask from a point and an angle.
|
||||
* @param param pointer to a `lv_draw_mask_param_t` to initialize
|
||||
* @param px X coordiante of a point of the line
|
||||
* @param py X coordiante of a point of the line
|
||||
* @param px X coordinate of a point of the line
|
||||
* @param py X coordinate of a point of the line
|
||||
* @param angle right 0 deg, bottom: 90
|
||||
* @param side and element of `lv_draw_mask_line_side_t` to describe which side to keep.
|
||||
* With `LV_DRAW_MASK_LINE_SIDE_LEFT/RIGHT` and horizontal line all pixels are kept
|
||||
@@ -250,7 +271,7 @@ void lv_draw_mask_angle_init(lv_draw_mask_angle_param_t * param, lv_coord_t vert
|
||||
* @param param param pointer to a `lv_draw_mask_param_t` to initialize
|
||||
* @param rect coordinates of the rectangle to affect (absolute coordinates)
|
||||
* @param radius radius of the rectangle
|
||||
* @param inv: true: keep the pixels inside teh rectangle; keep teh pixels outside of the rectangle
|
||||
* @param inv: true: keep the pixels inside the rectangle; keep the pixels outside of the rectangle
|
||||
*/
|
||||
void lv_draw_mask_radius_init(lv_draw_mask_radius_param_t * param, const lv_area_t * rect, lv_coord_t radius, bool inv);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -41,6 +41,7 @@ typedef struct {
|
||||
lv_style_int_t border_side;
|
||||
lv_opa_t border_opa;
|
||||
lv_blend_mode_t border_blend_mode;
|
||||
uint8_t border_post : 1; /*There is a border it will be drawn later. */
|
||||
|
||||
/*Outline*/
|
||||
lv_color_t outline_color;
|
||||
@@ -86,13 +87,15 @@ typedef struct {
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM void lv_draw_rect_dsc_init(lv_draw_rect_dsc_t * dsc);
|
||||
|
||||
//! @endcond
|
||||
|
||||
/**
|
||||
* Draw a rectangle
|
||||
* @param coords the coordinates of the rectangle
|
||||
* @param mask the rectangle will be drawn only in this mask
|
||||
* @param style pointer to a style
|
||||
* @param dsc pointer to an initialized `lv_draw_rect_dsc_t` variable
|
||||
*/
|
||||
void lv_draw_rect(const lv_area_t * coords, const lv_area_t * mask, lv_draw_rect_dsc_t * dsc);
|
||||
void lv_draw_rect(const lv_area_t * coords, const lv_area_t * mask, const lv_draw_rect_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Draw a pixel
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
* @param clip_area the triangle will be drawn only in this area
|
||||
* @param draw_dsc pointer to an initialized `lv_draw_rect_dsc_t` variable
|
||||
*/
|
||||
void lv_draw_triangle(const lv_point_t * points, const lv_area_t * clip_area, lv_draw_rect_dsc_t * draw_dsc)
|
||||
void lv_draw_triangle(const lv_point_t points[], const lv_area_t * clip_area, const lv_draw_rect_dsc_t * draw_dsc)
|
||||
{
|
||||
lv_draw_polygon(points, 3, clip_area, draw_dsc);
|
||||
}
|
||||
@@ -52,8 +52,8 @@ void lv_draw_triangle(const lv_point_t * points, const lv_area_t * clip_area, lv
|
||||
* @param clip_area polygon will be drawn only in this area
|
||||
* @param draw_dsc pointer to an initialized `lv_draw_rect_dsc_t` variable
|
||||
*/
|
||||
void lv_draw_polygon(const lv_point_t * points, uint16_t point_cnt, const lv_area_t * clip_area,
|
||||
lv_draw_rect_dsc_t * draw_dsc)
|
||||
void lv_draw_polygon(const lv_point_t points[], uint16_t point_cnt, const lv_area_t * clip_area,
|
||||
const lv_draw_rect_dsc_t * draw_dsc)
|
||||
{
|
||||
if(point_cnt < 3) return;
|
||||
if(points == NULL) return;
|
||||
@@ -71,7 +71,7 @@ void lv_draw_polygon(const lv_point_t * points, uint16_t point_cnt, const lv_are
|
||||
|
||||
bool is_common;
|
||||
lv_area_t poly_mask;
|
||||
is_common = lv_area_intersect(&poly_mask, &poly_coords, clip_area);
|
||||
is_common = _lv_area_intersect(&poly_mask, &poly_coords, clip_area);
|
||||
if(!is_common) return;
|
||||
|
||||
/*Find the lowest point*/
|
||||
@@ -85,7 +85,7 @@ void lv_draw_polygon(const lv_point_t * points, uint16_t point_cnt, const lv_are
|
||||
}
|
||||
}
|
||||
|
||||
lv_draw_mask_line_param_t * mp = lv_mem_buf_get(sizeof(lv_draw_mask_line_param_t) * point_cnt);
|
||||
lv_draw_mask_line_param_t * mp = _lv_mem_buf_get(sizeof(lv_draw_mask_line_param_t) * point_cnt);
|
||||
lv_draw_mask_line_param_t * mp_next = mp;
|
||||
|
||||
int32_t i_prev_left = y_min_i;
|
||||
@@ -156,7 +156,7 @@ void lv_draw_polygon(const lv_point_t * points, uint16_t point_cnt, const lv_are
|
||||
|
||||
lv_draw_mask_remove_custom(mp);
|
||||
|
||||
lv_mem_buf_release(mp);
|
||||
_lv_mem_buf_release(mp);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ extern "C" {
|
||||
* @param clip_area the triangle will be drawn only in this area
|
||||
* @param draw_dsc pointer to an initialized `lv_draw_rect_dsc_t` variable
|
||||
*/
|
||||
void lv_draw_triangle(const lv_point_t * points, const lv_area_t * clip, lv_draw_rect_dsc_t * draw_dsc);
|
||||
void lv_draw_triangle(const lv_point_t points[], const lv_area_t * clip, const lv_draw_rect_dsc_t * draw_dsc);
|
||||
|
||||
/**
|
||||
* Draw a polygon. Only convex polygons are supported.
|
||||
@@ -42,8 +42,8 @@ void lv_draw_triangle(const lv_point_t * points, const lv_area_t * clip, lv_draw
|
||||
* @param clip_area polygon will be drawn only in this area
|
||||
* @param draw_dsc pointer to an initialized `lv_draw_rect_dsc_t` variable
|
||||
*/
|
||||
void lv_draw_polygon(const lv_point_t * points, uint16_t point_cnt, const lv_area_t * mask,
|
||||
lv_draw_rect_dsc_t * draw_dsc);
|
||||
void lv_draw_polygon(const lv_point_t points[], uint16_t point_cnt, const lv_area_t * mask,
|
||||
const lv_draw_rect_dsc_t * draw_dsc);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static inline bool transform_anti_alias(lv_img_transform_dsc_t * dsc);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@@ -59,9 +58,9 @@ lv_color_t lv_img_buf_get_px_color(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t
|
||||
dsc->header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA) {
|
||||
uint8_t px_size = lv_img_cf_get_px_size(dsc->header.cf) >> 3;
|
||||
uint32_t px = dsc->header.w * y * px_size + x * px_size;
|
||||
lv_memcpy_small(&p_color, &buf_u8[px], sizeof(lv_color_t));
|
||||
_lv_memcpy_small(&p_color, &buf_u8[px], sizeof(lv_color_t));
|
||||
#if LV_COLOR_SIZE == 32
|
||||
p_color.ch.alpha = 0xFF; /*Only the color should be get so use a deafult alpha value*/
|
||||
p_color.ch.alpha = 0xFF; /*Only the color should be get so use a default alpha value*/
|
||||
#endif
|
||||
}
|
||||
else if(dsc->header.cf == LV_IMG_CF_INDEXED_1BIT) {
|
||||
@@ -246,12 +245,12 @@ void lv_img_buf_set_px_color(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_
|
||||
if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR || dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) {
|
||||
uint8_t px_size = lv_img_cf_get_px_size(dsc->header.cf) >> 3;
|
||||
uint32_t px = dsc->header.w * y * px_size + x * px_size;
|
||||
lv_memcpy_small(&buf_u8[px], &c, px_size);
|
||||
_lv_memcpy_small(&buf_u8[px], &c, px_size);
|
||||
}
|
||||
else if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA) {
|
||||
uint8_t px_size = lv_img_cf_get_px_size(dsc->header.cf) >> 3;
|
||||
uint32_t px = dsc->header.w * y * px_size + x * px_size;
|
||||
lv_memcpy_small(&buf_u8[px], &c, px_size - 1); /*-1 to not overwrite the alpha value*/
|
||||
_lv_memcpy_small(&buf_u8[px], &c, px_size - 1); /*-1 to not overwrite the alpha value*/
|
||||
}
|
||||
else if(dsc->header.cf == LV_IMG_CF_INDEXED_1BIT) {
|
||||
buf_u8 += sizeof(lv_color32_t) * 2; /*Skip the palette*/
|
||||
@@ -319,7 +318,7 @@ void lv_img_buf_set_palette(lv_img_dsc_t * dsc, uint8_t id, lv_color_t c)
|
||||
lv_color32_t c32;
|
||||
c32.full = lv_color_to32(c);
|
||||
uint8_t * buf = (uint8_t *)dsc->data;
|
||||
lv_memcpy_small(&buf[id * sizeof(c32)], &c32, sizeof(c32));
|
||||
_lv_memcpy_small(&buf[id * sizeof(c32)], &c32, sizeof(c32));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -336,7 +335,7 @@ lv_img_dsc_t * lv_img_buf_alloc(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf)
|
||||
if(dsc == NULL)
|
||||
return NULL;
|
||||
|
||||
lv_memset_00(dsc, sizeof(lv_img_dsc_t));
|
||||
_lv_memset_00(dsc, sizeof(lv_img_dsc_t));
|
||||
|
||||
/* Get image data size */
|
||||
dsc->data_size = lv_img_buf_get_img_size(w, h, cf);
|
||||
@@ -351,7 +350,7 @@ lv_img_dsc_t * lv_img_buf_alloc(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf)
|
||||
lv_mem_free(dsc);
|
||||
return NULL;
|
||||
}
|
||||
lv_memset_00((uint8_t *)dsc->data, dsc->data_size);
|
||||
_lv_memset_00((uint8_t *)dsc->data, dsc->data_size);
|
||||
|
||||
/* Fill in header */
|
||||
dsc->header.always_zero = 0;
|
||||
@@ -412,11 +411,13 @@ uint32_t lv_img_buf_get_img_size(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if LV_USE_IMG_TRANSFORM
|
||||
/**
|
||||
* Initialize a descriptor to tranform an image
|
||||
* Initialize a descriptor to transform an image
|
||||
* @param dsc pointer to an `lv_img_transform_dsc_t` variable whose `cfg` field is initialized
|
||||
*/
|
||||
void lv_img_buf_transform_init(lv_img_transform_dsc_t * dsc)
|
||||
void _lv_img_buf_transform_init(lv_img_transform_dsc_t * dsc)
|
||||
{
|
||||
dsc->tmp.pivot_x_256 = dsc->cfg.pivot_x * 256;
|
||||
dsc->tmp.pivot_y_256 = dsc->cfg.pivot_y * 256;
|
||||
@@ -425,15 +426,19 @@ void lv_img_buf_transform_init(lv_img_transform_dsc_t * dsc)
|
||||
int32_t angle_hight = angle_low + 1;
|
||||
int32_t angle_rem = dsc->cfg.angle - (angle_low * 10);
|
||||
|
||||
int32_t s1 = lv_trigo_sin(-angle_low);
|
||||
int32_t s2 = lv_trigo_sin(-angle_hight);
|
||||
int32_t s1 = _lv_trigo_sin(-angle_low);
|
||||
int32_t s2 = _lv_trigo_sin(-angle_hight);
|
||||
|
||||
int32_t c1 = lv_trigo_sin(-angle_low + 90);
|
||||
int32_t c2 = lv_trigo_sin(-angle_hight + 90);
|
||||
int32_t c1 = _lv_trigo_sin(-angle_low + 90);
|
||||
int32_t c2 = _lv_trigo_sin(-angle_hight + 90);
|
||||
|
||||
dsc->tmp.sinma = (s1 * (10 - angle_rem) + s2 * angle_rem) / 10;
|
||||
dsc->tmp.cosma = (c1 * (10 - angle_rem) + c2 * angle_rem) / 10;
|
||||
|
||||
/*Use smaller value to avoid overflow*/
|
||||
dsc->tmp.sinma = dsc->tmp.sinma >> (LV_TRIGO_SHIFT - _LV_TRANSFORM_TRIGO_SHIFT);
|
||||
dsc->tmp.cosma = dsc->tmp.cosma >> (LV_TRIGO_SHIFT - _LV_TRANSFORM_TRIGO_SHIFT);
|
||||
|
||||
dsc->tmp.chroma_keyed = lv_img_cf_is_chroma_keyed(dsc->cfg.cf) ? 1 : 0;
|
||||
dsc->tmp.has_alpha = lv_img_cf_has_alpha(dsc->cfg.cf) ? 1 : 0;
|
||||
if(dsc->cfg.cf == LV_IMG_CF_TRUE_COLOR || dsc->cfg.cf == LV_IMG_CF_TRUE_COLOR_ALPHA ||
|
||||
@@ -450,98 +455,14 @@ void lv_img_buf_transform_init(lv_img_transform_dsc_t * dsc)
|
||||
dsc->tmp.img_dsc.header.w = dsc->cfg.src_w;
|
||||
dsc->tmp.img_dsc.header.h = dsc->cfg.src_h;
|
||||
|
||||
dsc->tmp.zoom_inv = (256 * 256) / dsc->cfg.zoom;
|
||||
/* The inverse of the zoom will be sued during the transformation
|
||||
* + dsc->cfg.zoom / 2 for rounding*/
|
||||
dsc->tmp.zoom_inv = (((256 * 256) << _LV_ZOOM_INV_UPSCALE) + dsc->cfg.zoom / 2) / dsc->cfg.zoom;
|
||||
|
||||
dsc->res.opa = LV_OPA_COVER;
|
||||
dsc->res.color = dsc->cfg.color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get which color and opa would come to a pixel if it were rotated
|
||||
* @param dsc a descriptor initialized by `lv_img_buf_rotate_init`
|
||||
* @param x the coordinate which color and opa should be get
|
||||
* @param y the coordinate which color and opa should be get
|
||||
* @return true: there is valid pixel on these x/y coordinates; false: the rotated pixel was out of the image
|
||||
* @note the result is written back to `dsc->res_color` and `dsc->res_opa`
|
||||
*/
|
||||
bool lv_img_buf_transform(lv_img_transform_dsc_t * dsc, lv_coord_t x, lv_coord_t y)
|
||||
{
|
||||
const uint8_t * src_u8 = dsc->cfg.src;
|
||||
|
||||
/*Get the target point relative coordinates to the pivot*/
|
||||
int32_t xt = x - dsc->cfg.pivot_x;
|
||||
int32_t yt = y - dsc->cfg.pivot_y;
|
||||
|
||||
int32_t xs;
|
||||
int32_t ys;
|
||||
if(dsc->cfg.zoom == LV_IMG_ZOOM_NONE) {
|
||||
/*Get the source pixel from the upscaled image*/
|
||||
xs = ((dsc->tmp.cosma * xt - dsc->tmp.sinma * yt) >> (LV_TRIGO_SHIFT - 8)) + dsc->tmp.pivot_x_256;
|
||||
ys = ((dsc->tmp.sinma * xt + dsc->tmp.cosma * yt) >> (LV_TRIGO_SHIFT - 8)) + dsc->tmp.pivot_y_256;
|
||||
}
|
||||
else {
|
||||
xt *= dsc->tmp.zoom_inv;
|
||||
yt *= dsc->tmp.zoom_inv;
|
||||
xs = ((dsc->tmp.cosma * xt - dsc->tmp.sinma * yt) >> (LV_TRIGO_SHIFT)) + dsc->tmp.pivot_x_256;
|
||||
ys = ((dsc->tmp.sinma * xt + dsc->tmp.cosma * yt) >> (LV_TRIGO_SHIFT)) + dsc->tmp.pivot_y_256;
|
||||
}
|
||||
|
||||
/*Get the integer part of the source pixel*/
|
||||
int xs_int = xs >> 8;
|
||||
int ys_int = ys >> 8;
|
||||
|
||||
if(xs_int >= dsc->cfg.src_w) return false;
|
||||
else if(xs_int < 0) return false;
|
||||
|
||||
if(ys_int >= dsc->cfg.src_h) return false;
|
||||
else if(ys_int < 0) return false;
|
||||
|
||||
/* If the fractional < 0x70 mix the source pixel with the left/top pixel
|
||||
* If the fractional > 0x90 mix the source pixel with the right/bottom pixel
|
||||
* In the 0x70..0x90 range use the unchanged source pixel */
|
||||
|
||||
uint8_t px_size;
|
||||
uint32_t pxi;
|
||||
if(dsc->tmp.native_color) {
|
||||
if(dsc->tmp.has_alpha == 0) {
|
||||
px_size = LV_COLOR_SIZE >> 3;
|
||||
|
||||
pxi = dsc->cfg.src_w * ys_int * px_size + xs_int * px_size;
|
||||
lv_memcpy_small(&dsc->res.color, &src_u8[pxi], px_size);
|
||||
}
|
||||
else {
|
||||
px_size = LV_IMG_PX_SIZE_ALPHA_BYTE;
|
||||
pxi = dsc->cfg.src_w * ys_int * px_size + xs_int * px_size;
|
||||
lv_memcpy_small(&dsc->res.color, &src_u8[pxi], px_size - 1);
|
||||
dsc->res.opa = src_u8[pxi + px_size - 1];
|
||||
}
|
||||
}
|
||||
else {
|
||||
pxi = 0; /*unused*/
|
||||
px_size = 0; /*unused*/
|
||||
dsc->res.color = lv_img_buf_get_px_color(&dsc->tmp.img_dsc, xs_int, ys_int, dsc->cfg.color);
|
||||
dsc->res.opa = lv_img_buf_get_px_alpha(&dsc->tmp.img_dsc, xs_int, ys_int);
|
||||
}
|
||||
|
||||
if(dsc->tmp.chroma_keyed) {
|
||||
lv_color_t ct = LV_COLOR_TRANSP;
|
||||
if(dsc->res.color.full == ct.full) return false;
|
||||
}
|
||||
|
||||
if(dsc->cfg.antialias == false) return true;
|
||||
|
||||
dsc->tmp.xs = xs;
|
||||
dsc->tmp.ys = ys;
|
||||
dsc->tmp.xs_int = xs_int;
|
||||
dsc->tmp.ys_int = ys_int;
|
||||
dsc->tmp.pxi = pxi;
|
||||
dsc->tmp.px_size = px_size;
|
||||
|
||||
bool ret;
|
||||
ret = transform_anti_alias(dsc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get the area of a rectangle if its rotated and scaled
|
||||
@@ -552,23 +473,49 @@ bool lv_img_buf_transform(lv_img_transform_dsc_t * dsc, lv_coord_t x, lv_coord_t
|
||||
* @param zoom zoom, (256 no zoom)
|
||||
* @param pivot x,y pivot coordinates of rotation
|
||||
*/
|
||||
void lv_img_buf_get_transformed_area(lv_area_t * res, lv_coord_t w, lv_coord_t h, int16_t angle, uint16_t zoom,
|
||||
lv_point_t * pivot)
|
||||
void _lv_img_buf_get_transformed_area(lv_area_t * res, lv_coord_t w, lv_coord_t h, int16_t angle, uint16_t zoom,
|
||||
const lv_point_t * pivot)
|
||||
{
|
||||
#if LV_USE_IMG_TRANSFORM
|
||||
if(angle == 0 && zoom == LV_IMG_ZOOM_NONE) {
|
||||
res->x1 = 0;
|
||||
res->y1 = 0;
|
||||
res->x2 = w - 1;
|
||||
res->y2 = h - 1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
res->x1 = (((-pivot->x) * zoom) >> 8) - 1;
|
||||
res->y1 = (((-pivot->y) * zoom) >> 8) - 1;
|
||||
res->x2 = (((w - pivot->x) * zoom) >> 8) + 2;
|
||||
res->y2 = (((h - pivot->y) * zoom) >> 8) + 2;
|
||||
|
||||
if(angle == 0) {
|
||||
res->x1 += pivot->x;
|
||||
res->y1 += pivot->y;
|
||||
res->x2 += pivot->x;
|
||||
res->y2 += pivot->y;
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t angle_low = angle / 10;
|
||||
int32_t angle_hight = angle_low + 1;
|
||||
int32_t angle_rem = angle - (angle_low * 10);
|
||||
|
||||
int32_t s1 = lv_trigo_sin(angle_low);
|
||||
int32_t s2 = lv_trigo_sin(angle_hight);
|
||||
int32_t s1 = _lv_trigo_sin(angle_low);
|
||||
int32_t s2 = _lv_trigo_sin(angle_hight);
|
||||
|
||||
int32_t c1 = lv_trigo_sin(angle_low + 90);
|
||||
int32_t c2 = lv_trigo_sin(angle_hight + 90);
|
||||
int32_t c1 = _lv_trigo_sin(angle_low + 90);
|
||||
int32_t c2 = _lv_trigo_sin(angle_hight + 90);
|
||||
|
||||
int32_t sinma = (s1 * (10 - angle_rem) + s2 * angle_rem) / 10;
|
||||
int32_t cosma = (c1 * (10 - angle_rem) + c2 * angle_rem) / 10;
|
||||
|
||||
/*Use smaller value to avoid overflow*/
|
||||
sinma = sinma >> (LV_TRIGO_SHIFT - _LV_TRANSFORM_TRIGO_SHIFT);
|
||||
cosma = cosma >> (LV_TRIGO_SHIFT - _LV_TRANSFORM_TRIGO_SHIFT);
|
||||
|
||||
lv_point_t lt;
|
||||
lv_point_t rt;
|
||||
lv_point_t lb;
|
||||
@@ -577,50 +524,54 @@ void lv_img_buf_get_transformed_area(lv_area_t * res, lv_coord_t w, lv_coord_t h
|
||||
lv_coord_t xt;
|
||||
lv_coord_t yt;
|
||||
|
||||
lv_area_t a;
|
||||
a.x1 = ((-pivot->x) * zoom) >> 8;
|
||||
a.y1 = ((-pivot->y) * zoom) >> 8;
|
||||
a.x2 = ((w - pivot->x) * zoom) >> 8;
|
||||
a.y2 = ((h - pivot->y) * zoom) >> 8;
|
||||
xt = res->x1;
|
||||
yt = res->y1;
|
||||
lt.x = ((cosma * xt - sinma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->x;
|
||||
lt.y = ((sinma * xt + cosma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->y;
|
||||
|
||||
xt = a.x1;
|
||||
yt = a.y1;
|
||||
lt.x = ((cosma * xt - sinma * yt) >> LV_TRIGO_SHIFT) + pivot->x;
|
||||
lt.y = ((sinma * xt + cosma * yt) >> LV_TRIGO_SHIFT) + pivot->y;
|
||||
xt = res->x2;
|
||||
yt = res->y1;
|
||||
rt.x = ((cosma * xt - sinma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->x;
|
||||
rt.y = ((sinma * xt + cosma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->y;
|
||||
|
||||
xt = a.x2;
|
||||
yt = a.y1;
|
||||
rt.x = ((cosma * xt - sinma * yt) >> LV_TRIGO_SHIFT) + pivot->x;
|
||||
rt.y = ((sinma * xt + cosma * yt) >> LV_TRIGO_SHIFT) + pivot->y;
|
||||
xt = res->x1;
|
||||
yt = res->y2;
|
||||
lb.x = ((cosma * xt - sinma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->x;
|
||||
lb.y = ((sinma * xt + cosma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->y;
|
||||
|
||||
xt = a.x1;
|
||||
yt = a.y2;
|
||||
lb.x = ((cosma * xt - sinma * yt) >> LV_TRIGO_SHIFT) + pivot->x;
|
||||
lb.y = ((sinma * xt + cosma * yt) >> LV_TRIGO_SHIFT) + pivot->y;
|
||||
|
||||
xt = a.x2;
|
||||
yt = a.y2;
|
||||
rb.x = ((cosma * xt - sinma * yt) >> LV_TRIGO_SHIFT) + pivot->x;
|
||||
rb.y = ((sinma * xt + cosma * yt) >> LV_TRIGO_SHIFT) + pivot->y;
|
||||
xt = res->x2;
|
||||
yt = res->y2;
|
||||
rb.x = ((cosma * xt - sinma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->x;
|
||||
rb.y = ((sinma * xt + cosma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->y;
|
||||
|
||||
res->x1 = LV_MATH_MIN4(lb.x, lt.x, rb.x, rt.x);
|
||||
res->x2 = LV_MATH_MAX4(lb.x, lt.x, rb.x, rt.x);
|
||||
res->y1 = LV_MATH_MIN4(lb.y, lt.y, rb.y, rt.y);
|
||||
res->y2 = LV_MATH_MAX4(lb.y, lt.y, rb.y, rt.y);
|
||||
|
||||
#else
|
||||
LV_UNUSED(angle);
|
||||
LV_UNUSED(zoom);
|
||||
LV_UNUSED(pivot);
|
||||
res->x1 = 0;
|
||||
res->y1 = 0;
|
||||
res->x2 = w - 1;
|
||||
res->y2 = h - 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
static inline bool transform_anti_alias(lv_img_transform_dsc_t * dsc)
|
||||
#if LV_USE_IMG_TRANSFORM
|
||||
/**
|
||||
* Continue transformation by taking the neighbors into account
|
||||
* @param dsc pointer to the transformation descriptor
|
||||
*/
|
||||
bool _lv_img_buf_transform_anti_alias(lv_img_transform_dsc_t * dsc)
|
||||
{
|
||||
const uint8_t * src_u8 = dsc->cfg.src;
|
||||
|
||||
/*Get the fractional part of the source pixel*/
|
||||
int xs_fract = dsc->tmp.xs & 0xff;
|
||||
int ys_fract = dsc->tmp.ys & 0xff;
|
||||
int32_t xn; /*x neightboor*/
|
||||
int32_t xn; /*x neighbor*/
|
||||
lv_opa_t xr; /*x mix ratio*/
|
||||
|
||||
if(xs_fract < 0x70) {
|
||||
@@ -638,7 +589,7 @@ static inline bool transform_anti_alias(lv_img_transform_dsc_t * dsc)
|
||||
xr = 0xFF;
|
||||
}
|
||||
|
||||
int32_t yn; /*x neightboor*/
|
||||
int32_t yn; /*x neighbor*/
|
||||
lv_opa_t yr; /*x mix ratio*/
|
||||
|
||||
if(ys_fract < 0x70) {
|
||||
@@ -669,10 +620,10 @@ static inline bool transform_anti_alias(lv_img_transform_dsc_t * dsc)
|
||||
lv_opa_t a11 = 0;
|
||||
|
||||
if(dsc->tmp.native_color) {
|
||||
lv_memcpy_small(&c01, &src_u8[dsc->tmp.pxi + dsc->tmp.px_size * xn], sizeof(lv_color_t));
|
||||
lv_memcpy_small(&c10, &src_u8[dsc->tmp.pxi + dsc->cfg.src_w * dsc->tmp.px_size * yn], sizeof(lv_color_t));
|
||||
lv_memcpy_small(&c11, &src_u8[dsc->tmp.pxi + dsc->cfg.src_w * dsc->tmp.px_size * yn + dsc->tmp.px_size * xn],
|
||||
sizeof(lv_color_t));
|
||||
_lv_memcpy_small(&c01, &src_u8[dsc->tmp.pxi + dsc->tmp.px_size * xn], sizeof(lv_color_t));
|
||||
_lv_memcpy_small(&c10, &src_u8[dsc->tmp.pxi + dsc->cfg.src_w * dsc->tmp.px_size * yn], sizeof(lv_color_t));
|
||||
_lv_memcpy_small(&c11, &src_u8[dsc->tmp.pxi + dsc->cfg.src_w * dsc->tmp.px_size * yn + dsc->tmp.px_size * xn],
|
||||
sizeof(lv_color_t));
|
||||
if(dsc->tmp.has_alpha) {
|
||||
a10 = src_u8[dsc->tmp.pxi + dsc->tmp.px_size * xn + dsc->tmp.px_size - 1];
|
||||
a01 = src_u8[dsc->tmp.pxi + dsc->cfg.src_w * dsc->tmp.px_size * yn + dsc->tmp.px_size - 1];
|
||||
@@ -728,3 +679,8 @@ static inline bool transform_anti_alias(lv_img_transform_dsc_t * dsc)
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@ extern "C" {
|
||||
#define LV_IMG_PX_SIZE_ALPHA_BYTE 4
|
||||
#endif
|
||||
|
||||
|
||||
#define LV_IMG_BUF_SIZE_TRUE_COLOR(w, h) ((LV_COLOR_SIZE / 8) * w * h)
|
||||
#define LV_IMG_BUF_SIZE_TRUE_COLOR_CHROMA_KEYED(w, h) ((LV_COLOR_SIZE / 8) * w * h)
|
||||
#define LV_IMG_BUF_SIZE_TRUE_COLOR_ALPHA(w, h) (LV_IMG_PX_SIZE_ALPHA_BYTE * w * h)
|
||||
@@ -49,6 +48,9 @@ extern "C" {
|
||||
|
||||
#define LV_IMG_ZOOM_NONE 256
|
||||
|
||||
#define _LV_TRANSFORM_TRIGO_SHIFT 10
|
||||
#define _LV_ZOOM_INV_UPSCALE 5
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
@@ -101,12 +103,28 @@ typedef uint8_t lv_img_cf_t;
|
||||
|
||||
|
||||
/**
|
||||
* LittlevGL image header
|
||||
* LVGL image header
|
||||
*/
|
||||
/* The first 8 bit is very important to distinguish the different source types.
|
||||
* For more info see `lv_img_get_src_type()` in lv_img.c
|
||||
* On big endian systems the order is reversed so cf and always_zero must be at
|
||||
* the end of the struct.
|
||||
* */
|
||||
#if LV_BIG_ENDIAN_SYSTEM
|
||||
typedef struct {
|
||||
|
||||
uint32_t h : 11; /*Height of the image map*/
|
||||
uint32_t w : 11; /*Width of the image map*/
|
||||
uint32_t reserved : 2; /*Reserved to be used later*/
|
||||
uint32_t always_zero : 3; /*It the upper bits of the first byte. Always zero to look like a
|
||||
non-printable character*/
|
||||
uint32_t cf : 5; /* Color format: See `lv_img_color_format_t`*/
|
||||
|
||||
|
||||
} lv_img_header_t;
|
||||
#else
|
||||
typedef struct {
|
||||
|
||||
/* The first 8 bit is very important to distinguish the different source types.
|
||||
* For more info see `lv_img_get_src_type()` in lv_img.c */
|
||||
uint32_t cf : 5; /* Color format: See `lv_img_color_format_t`*/
|
||||
uint32_t always_zero : 3; /*It the upper bits of the first byte. Always zero to look like a
|
||||
non-printable character*/
|
||||
@@ -116,7 +134,7 @@ typedef struct {
|
||||
uint32_t w : 11; /*Width of the image map*/
|
||||
uint32_t h : 11; /*Height of the image map*/
|
||||
} lv_img_header_t;
|
||||
|
||||
#endif
|
||||
|
||||
/** Image header it is compatible with
|
||||
* the result from image converter utility*/
|
||||
@@ -157,7 +175,7 @@ typedef struct {
|
||||
uint8_t has_alpha : 1;
|
||||
uint8_t native_color : 1;
|
||||
|
||||
uint16_t zoom_inv;
|
||||
uint32_t zoom_inv;
|
||||
|
||||
/*Runtime data*/
|
||||
lv_coord_t xs;
|
||||
@@ -252,11 +270,19 @@ void lv_img_buf_free(lv_img_dsc_t * dsc);
|
||||
uint32_t lv_img_buf_get_img_size(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf);
|
||||
|
||||
|
||||
#if LV_USE_IMG_TRANSFORM
|
||||
/**
|
||||
* Initialize a descriptor to rotate an image
|
||||
* @param dsc pointer to an `lv_img_transform_dsc_t` variable whose `cfg` field is initialized
|
||||
*/
|
||||
void lv_img_buf_transform_init(lv_img_transform_dsc_t * dsc);
|
||||
void _lv_img_buf_transform_init(lv_img_transform_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Continue transformation by taking the neighbors into account
|
||||
* @param dsc pointer to the transformation descriptor
|
||||
*/
|
||||
bool _lv_img_buf_transform_anti_alias(lv_img_transform_dsc_t * dsc);
|
||||
|
||||
|
||||
/**
|
||||
* Get which color and opa would come to a pixel if it were rotated
|
||||
@@ -266,8 +292,87 @@ void lv_img_buf_transform_init(lv_img_transform_dsc_t * dsc);
|
||||
* @return true: there is valid pixel on these x/y coordinates; false: the rotated pixel was out of the image
|
||||
* @note the result is written back to `dsc->res_color` and `dsc->res_opa`
|
||||
*/
|
||||
bool lv_img_buf_transform(lv_img_transform_dsc_t * dsc, lv_coord_t x, lv_coord_t y);
|
||||
static inline bool _lv_img_buf_transform(lv_img_transform_dsc_t * dsc, lv_coord_t x, lv_coord_t y)
|
||||
{
|
||||
const uint8_t * src_u8 = (const uint8_t *)dsc->cfg.src;
|
||||
|
||||
/*Get the target point relative coordinates to the pivot*/
|
||||
int32_t xt = x - dsc->cfg.pivot_x;
|
||||
int32_t yt = y - dsc->cfg.pivot_y;
|
||||
|
||||
int32_t xs;
|
||||
int32_t ys;
|
||||
if(dsc->cfg.zoom == LV_IMG_ZOOM_NONE) {
|
||||
/*Get the source pixel from the upscaled image*/
|
||||
xs = ((dsc->tmp.cosma * xt - dsc->tmp.sinma * yt) >> (_LV_TRANSFORM_TRIGO_SHIFT - 8)) + dsc->tmp.pivot_x_256;
|
||||
ys = ((dsc->tmp.sinma * xt + dsc->tmp.cosma * yt) >> (_LV_TRANSFORM_TRIGO_SHIFT - 8)) + dsc->tmp.pivot_y_256;
|
||||
}
|
||||
else if(dsc->cfg.angle == 0) {
|
||||
xt = (int32_t)((int32_t)xt * dsc->tmp.zoom_inv) >> _LV_ZOOM_INV_UPSCALE;
|
||||
yt = (int32_t)((int32_t)yt * dsc->tmp.zoom_inv) >> _LV_ZOOM_INV_UPSCALE;
|
||||
xs = xt + dsc->tmp.pivot_x_256;
|
||||
ys = yt + dsc->tmp.pivot_y_256;
|
||||
}
|
||||
else {
|
||||
xt = (int32_t)((int32_t)xt * dsc->tmp.zoom_inv) >> _LV_ZOOM_INV_UPSCALE;
|
||||
yt = (int32_t)((int32_t)yt * dsc->tmp.zoom_inv) >> _LV_ZOOM_INV_UPSCALE;
|
||||
xs = ((dsc->tmp.cosma * xt - dsc->tmp.sinma * yt) >> (_LV_TRANSFORM_TRIGO_SHIFT)) + dsc->tmp.pivot_x_256;
|
||||
ys = ((dsc->tmp.sinma * xt + dsc->tmp.cosma * yt) >> (_LV_TRANSFORM_TRIGO_SHIFT)) + dsc->tmp.pivot_y_256;
|
||||
}
|
||||
|
||||
/*Get the integer part of the source pixel*/
|
||||
int32_t xs_int = xs >> 8;
|
||||
int32_t ys_int = ys >> 8;
|
||||
|
||||
if(xs_int >= dsc->cfg.src_w) return false;
|
||||
else if(xs_int < 0) return false;
|
||||
|
||||
if(ys_int >= dsc->cfg.src_h) return false;
|
||||
else if(ys_int < 0) return false;
|
||||
|
||||
uint8_t px_size;
|
||||
uint32_t pxi;
|
||||
if(dsc->tmp.native_color) {
|
||||
if(dsc->tmp.has_alpha == 0) {
|
||||
px_size = LV_COLOR_SIZE >> 3;
|
||||
|
||||
pxi = dsc->cfg.src_w * ys_int * px_size + xs_int * px_size;
|
||||
_lv_memcpy_small(&dsc->res.color, &src_u8[pxi], px_size);
|
||||
}
|
||||
else {
|
||||
px_size = LV_IMG_PX_SIZE_ALPHA_BYTE;
|
||||
pxi = dsc->cfg.src_w * ys_int * px_size + xs_int * px_size;
|
||||
_lv_memcpy_small(&dsc->res.color, &src_u8[pxi], px_size - 1);
|
||||
dsc->res.opa = src_u8[pxi + px_size - 1];
|
||||
}
|
||||
}
|
||||
else {
|
||||
pxi = 0; /*unused*/
|
||||
px_size = 0; /*unused*/
|
||||
dsc->res.color = lv_img_buf_get_px_color(&dsc->tmp.img_dsc, xs_int, ys_int, dsc->cfg.color);
|
||||
dsc->res.opa = lv_img_buf_get_px_alpha(&dsc->tmp.img_dsc, xs_int, ys_int);
|
||||
}
|
||||
|
||||
if(dsc->tmp.chroma_keyed) {
|
||||
lv_color_t ct = LV_COLOR_TRANSP;
|
||||
if(dsc->res.color.full == ct.full) return false;
|
||||
}
|
||||
|
||||
if(dsc->cfg.antialias == false) return true;
|
||||
|
||||
dsc->tmp.xs = xs;
|
||||
dsc->tmp.ys = ys;
|
||||
dsc->tmp.xs_int = xs_int;
|
||||
dsc->tmp.ys_int = ys_int;
|
||||
dsc->tmp.pxi = pxi;
|
||||
dsc->tmp.px_size = px_size;
|
||||
|
||||
bool ret;
|
||||
ret = _lv_img_buf_transform_anti_alias(dsc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* Get the area of a rectangle if its rotated and scaled
|
||||
* @param res store the coordinates here
|
||||
@@ -277,8 +382,8 @@ bool lv_img_buf_transform(lv_img_transform_dsc_t * dsc, lv_coord_t x, lv_coord_t
|
||||
* @param zoom zoom, (256 no zoom)
|
||||
* @param pivot x,y pivot coordinates of rotation
|
||||
*/
|
||||
void lv_img_buf_get_transformed_area(lv_area_t * res, lv_coord_t w, lv_coord_t h, int16_t angle, uint16_t zoom,
|
||||
lv_point_t * pivot);
|
||||
void _lv_img_buf_get_transformed_area(lv_area_t * res, lv_coord_t w, lv_coord_t h, int16_t angle, uint16_t zoom,
|
||||
const lv_point_t * pivot);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "../lv_misc/lv_debug.h"
|
||||
#include "lv_img_cache.h"
|
||||
#include "lv_img_decoder.h"
|
||||
#include "lv_draw_img.h"
|
||||
@@ -59,10 +59,10 @@ static uint16_t entry_cnt;
|
||||
* The image will be left open meaning if the image decoder open callback allocated memory then it will remain.
|
||||
* The image is closed if a new image is opened and the new image takes its place in the cache.
|
||||
* @param src source of the image. Path to file or pointer to an `lv_img_dsc_t` variable
|
||||
* @param style style of the image
|
||||
* @param color color The color of the image with `LV_IMG_CF_ALPHA_...`
|
||||
* @return pointer to the cache entry or NULL if can open the image
|
||||
*/
|
||||
lv_img_cache_entry_t * lv_img_cache_open(const void * src, lv_color_t color)
|
||||
lv_img_cache_entry_t * _lv_img_cache_open(const void * src, lv_color_t color)
|
||||
{
|
||||
if(entry_cnt == 0) {
|
||||
LV_LOG_WARN("lv_img_cache_open: the cache size is 0");
|
||||
@@ -130,8 +130,8 @@ lv_img_cache_entry_t * lv_img_cache_open(const void * src, lv_color_t color)
|
||||
if(open_res == LV_RES_INV) {
|
||||
LV_LOG_WARN("Image draw cannot open the image resource");
|
||||
lv_img_decoder_close(&cached_src->dec_dsc);
|
||||
lv_memset_00(&cached_src->dec_dsc, sizeof(lv_img_decoder_dsc_t));
|
||||
lv_memset_00(cached_src, sizeof(lv_img_cache_entry_t));
|
||||
_lv_memset_00(&cached_src->dec_dsc, sizeof(lv_img_decoder_dsc_t));
|
||||
_lv_memset_00(cached_src, sizeof(lv_img_cache_entry_t));
|
||||
cached_src->life = INT32_MIN; /*Make the empty entry very "weak" to force its use */
|
||||
return NULL;
|
||||
}
|
||||
@@ -175,8 +175,8 @@ void lv_img_cache_set_size(uint16_t new_entry_cnt)
|
||||
/*Clean the cache*/
|
||||
uint16_t i;
|
||||
for(i = 0; i < entry_cnt; i++) {
|
||||
lv_memset_00(&LV_GC_ROOT(_lv_img_cache_array)[i].dec_dsc, sizeof(lv_img_decoder_dsc_t));
|
||||
lv_memset_00(&LV_GC_ROOT(_lv_img_cache_array)[i], sizeof(lv_img_cache_entry_t));
|
||||
_lv_memset_00(&LV_GC_ROOT(_lv_img_cache_array)[i].dec_dsc, sizeof(lv_img_decoder_dsc_t));
|
||||
_lv_memset_00(&LV_GC_ROOT(_lv_img_cache_array)[i], sizeof(lv_img_cache_entry_t));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,8 +197,8 @@ void lv_img_cache_invalidate_src(const void * src)
|
||||
lv_img_decoder_close(&cache[i].dec_dsc);
|
||||
}
|
||||
|
||||
lv_memset_00(&cache[i].dec_dsc, sizeof(lv_img_decoder_dsc_t));
|
||||
lv_memset_00(&cache[i], sizeof(lv_img_cache_entry_t));
|
||||
_lv_memset_00(&cache[i].dec_dsc, sizeof(lv_img_decoder_dsc_t));
|
||||
_lv_memset_00(&cache[i], sizeof(lv_img_cache_entry_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,10 +46,10 @@ typedef struct {
|
||||
* The image will be left open meaning if the image decoder open callback allocated memory then it will remain.
|
||||
* The image is closed if a new image is opened and the new image takes its place in the cache.
|
||||
* @param src source of the image. Path to file or pointer to an `lv_img_dsc_t` variable
|
||||
* @param style style of the image
|
||||
* @param color The color of the image with `LV_IMG_CF_ALPHA_...`
|
||||
* @return pointer to the cache entry or NULL if can open the image
|
||||
*/
|
||||
lv_img_cache_entry_t * lv_img_cache_open(const void * src, lv_color_t color);
|
||||
lv_img_cache_entry_t * _lv_img_cache_open(const void * src, lv_color_t color);
|
||||
|
||||
/**
|
||||
* Set the number of images to be cached.
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_img_decoder.h"
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "../lv_misc/lv_debug.h"
|
||||
#include "../lv_draw/lv_draw_img.h"
|
||||
#include "../lv_misc/lv_ll.h"
|
||||
#include "../lv_misc/lv_color.h"
|
||||
@@ -59,9 +59,9 @@ static lv_res_t lv_img_decoder_built_in_line_indexed(lv_img_decoder_dsc_t * dsc,
|
||||
/**
|
||||
* Initialize the image decoder module
|
||||
* */
|
||||
void lv_img_decoder_init(void)
|
||||
void _lv_img_decoder_init(void)
|
||||
{
|
||||
lv_ll_init(&LV_GC_ROOT(_lv_img_defoder_ll), sizeof(lv_img_decoder_t));
|
||||
_lv_ll_init(&LV_GC_ROOT(_lv_img_defoder_ll), sizeof(lv_img_decoder_t));
|
||||
|
||||
lv_img_decoder_t * decoder;
|
||||
|
||||
@@ -89,10 +89,13 @@ void lv_img_decoder_init(void)
|
||||
lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header)
|
||||
{
|
||||
header->always_zero = 0;
|
||||
header->h = 0;
|
||||
header->w = 0;
|
||||
header->cf = LV_IMG_CF_UNKNOWN;
|
||||
|
||||
lv_res_t res = LV_RES_INV;
|
||||
lv_img_decoder_t * d;
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_img_defoder_ll), d) {
|
||||
_LV_LL_READ(LV_GC_ROOT(_lv_img_defoder_ll), d) {
|
||||
res = LV_RES_INV;
|
||||
if(d->info_cb) {
|
||||
res = d->info_cb(d, src, header);
|
||||
@@ -111,7 +114,7 @@ lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header)
|
||||
* 1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_add_drv()`)
|
||||
* 2) Variable: Pointer to an `lv_img_dsc_t` variable
|
||||
* 3) Symbol: E.g. `LV_SYMBOL_OK`
|
||||
* @param style the style of the image
|
||||
* @param color The color of the image with `LV_IMG_CF_ALPHA_...`
|
||||
* @return LV_RES_OK: opened the image. `dsc->img_data` and `dsc->header` are set.
|
||||
* LV_RES_INV: none of the registered image decoders were able to open the image.
|
||||
*/
|
||||
@@ -133,7 +136,7 @@ lv_res_t lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, lv_co
|
||||
lv_res_t res = LV_RES_INV;
|
||||
|
||||
lv_img_decoder_t * d;
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_img_defoder_ll), d) {
|
||||
_LV_LL_READ(LV_GC_ROOT(_lv_img_defoder_ll), d) {
|
||||
/*Info an Open callbacks are required*/
|
||||
if(d->info_cb == NULL || d->open_cb == NULL) continue;
|
||||
|
||||
@@ -150,10 +153,6 @@ lv_res_t lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, lv_co
|
||||
if(res == LV_RES_OK) break;
|
||||
}
|
||||
|
||||
if(res == LV_RES_INV) {
|
||||
lv_memset_00(dsc, sizeof(lv_img_decoder_dsc_t));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -197,11 +196,11 @@ void lv_img_decoder_close(lv_img_decoder_dsc_t * dsc)
|
||||
lv_img_decoder_t * lv_img_decoder_create(void)
|
||||
{
|
||||
lv_img_decoder_t * decoder;
|
||||
decoder = lv_ll_ins_head(&LV_GC_ROOT(_lv_img_defoder_ll));
|
||||
decoder = _lv_ll_ins_head(&LV_GC_ROOT(_lv_img_defoder_ll));
|
||||
LV_ASSERT_MEM(decoder);
|
||||
if(decoder == NULL) return NULL;
|
||||
|
||||
lv_memset_00(decoder, sizeof(lv_img_decoder_t));
|
||||
_lv_memset_00(decoder, sizeof(lv_img_decoder_t));
|
||||
|
||||
return decoder;
|
||||
}
|
||||
@@ -212,7 +211,7 @@ lv_img_decoder_t * lv_img_decoder_create(void)
|
||||
*/
|
||||
void lv_img_decoder_delete(lv_img_decoder_t * decoder)
|
||||
{
|
||||
lv_ll_remove(&LV_GC_ROOT(_lv_img_defoder_ll), decoder);
|
||||
_lv_ll_remove(&LV_GC_ROOT(_lv_img_defoder_ll), decoder);
|
||||
lv_mem_free(decoder);
|
||||
}
|
||||
|
||||
@@ -341,7 +340,7 @@ lv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder
|
||||
LV_LOG_ERROR("img_decoder_built_in_open: out of memory");
|
||||
return LV_RES_INV;
|
||||
}
|
||||
lv_memset_00(dsc->user_data, sizeof(lv_img_decoder_built_in_data_t));
|
||||
_lv_memset_00(dsc->user_data, sizeof(lv_img_decoder_built_in_data_t));
|
||||
}
|
||||
|
||||
lv_img_decoder_built_in_data_t * user_data = dsc->user_data;
|
||||
@@ -353,7 +352,7 @@ lv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
lv_memcpy_small(user_data->f, &f, sizeof(f));
|
||||
_lv_memcpy_small(user_data->f, &f, sizeof(f));
|
||||
|
||||
#else
|
||||
LV_LOG_WARN("Image built-in decoder cannot read file because LV_USE_FILESYSTEM = 0");
|
||||
@@ -399,7 +398,7 @@ lv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder
|
||||
lv_img_decoder_built_in_close(decoder, dsc);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
lv_memset_00(dsc->user_data, sizeof(lv_img_decoder_built_in_data_t));
|
||||
_lv_memset_00(dsc->user_data, sizeof(lv_img_decoder_built_in_data_t));
|
||||
}
|
||||
|
||||
lv_img_decoder_built_in_data_t * user_data = dsc->user_data;
|
||||
@@ -560,7 +559,7 @@ static lv_res_t lv_img_decoder_built_in_line_true_color(lv_img_decoder_dsc_t * d
|
||||
}
|
||||
uint32_t btr = len * (px_size >> 3);
|
||||
uint32_t br = 0;
|
||||
lv_fs_read(user_data->f, buf, btr, &br);
|
||||
res = lv_fs_read(user_data->f, buf, btr, &br);
|
||||
if(res != LV_FS_RES_OK || btr != br) {
|
||||
LV_LOG_WARN("Built-in image decoder read failed");
|
||||
return LV_RES_INV;
|
||||
@@ -568,6 +567,11 @@ static lv_res_t lv_img_decoder_built_in_line_true_color(lv_img_decoder_dsc_t * d
|
||||
|
||||
return LV_RES_OK;
|
||||
#else
|
||||
LV_UNUSED(dsc);
|
||||
LV_UNUSED(x);
|
||||
LV_UNUSED(y);
|
||||
LV_UNUSED(len);
|
||||
LV_UNUSED(buf);
|
||||
LV_LOG_WARN("Image built-in decoder cannot read file because LV_USE_FILESYSTEM = 0");
|
||||
return LV_RES_INV;
|
||||
#endif
|
||||
@@ -639,7 +643,7 @@ static lv_res_t lv_img_decoder_built_in_line_alpha(lv_img_decoder_dsc_t * dsc, l
|
||||
|
||||
#if LV_USE_FILESYSTEM
|
||||
lv_img_decoder_built_in_data_t * user_data = dsc->user_data;
|
||||
uint8_t * fs_buf = lv_mem_buf_get(w);
|
||||
uint8_t * fs_buf = _lv_mem_buf_get(w);
|
||||
#endif
|
||||
|
||||
const uint8_t * data_tmp = NULL;
|
||||
@@ -673,7 +677,7 @@ static lv_res_t lv_img_decoder_built_in_line_alpha(lv_img_decoder_dsc_t * dsc, l
|
||||
}
|
||||
}
|
||||
#if LV_USE_FILESYSTEM
|
||||
lv_mem_buf_release(fs_buf);
|
||||
_lv_mem_buf_release(fs_buf);
|
||||
#endif
|
||||
return LV_RES_OK;
|
||||
|
||||
@@ -727,7 +731,7 @@ static lv_res_t lv_img_decoder_built_in_line_indexed(lv_img_decoder_dsc_t * dsc,
|
||||
lv_img_decoder_built_in_data_t * user_data = dsc->user_data;
|
||||
|
||||
#if LV_USE_FILESYSTEM
|
||||
uint8_t * fs_buf = lv_mem_buf_get(w);
|
||||
uint8_t * fs_buf = _lv_mem_buf_get(w);
|
||||
#endif
|
||||
const uint8_t * data_tmp = NULL;
|
||||
if(dsc->src_type == LV_IMG_SRC_VARIABLE) {
|
||||
@@ -771,7 +775,7 @@ static lv_res_t lv_img_decoder_built_in_line_indexed(lv_img_decoder_dsc_t * dsc,
|
||||
}
|
||||
}
|
||||
#if LV_USE_FILESYSTEM
|
||||
lv_mem_buf_release(fs_buf);
|
||||
_lv_mem_buf_release(fs_buf);
|
||||
#endif
|
||||
return LV_RES_OK;
|
||||
#else
|
||||
|
||||
@@ -135,7 +135,7 @@ typedef struct _lv_img_decoder_dsc {
|
||||
/**
|
||||
* Initialize the image decoder module
|
||||
*/
|
||||
void lv_img_decoder_init(void);
|
||||
void _lv_img_decoder_init(void);
|
||||
|
||||
/**
|
||||
* Get information about an image.
|
||||
@@ -157,7 +157,7 @@ lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header);
|
||||
* 1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_add_drv()`)
|
||||
* 2) Variable: Pointer to an `lv_img_dsc_t` variable
|
||||
* 3) Symbol: E.g. `LV_SYMBOL_OK`
|
||||
* @param style the style of the image
|
||||
* @param color The color of the image with `LV_IMG_CF_ALPHA_...`
|
||||
* @return LV_RES_OK: opened the image. `dsc->img_data` and `dsc->header` are set.
|
||||
* LV_RES_INV: none of the registered image decoders were able to open the image.
|
||||
*/
|
||||
@@ -221,8 +221,6 @@ void lv_img_decoder_set_read_line_cb(lv_img_decoder_t * decoder, lv_img_decoder_
|
||||
*/
|
||||
void lv_img_decoder_set_close_cb(lv_img_decoder_t * decoder, lv_img_decoder_close_f_t close_cb);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get info about a built-in image
|
||||
* @param decoder the decoder where this function belongs
|
||||
|
||||
@@ -71,6 +71,10 @@ typedef struct _lv_font_struct {
|
||||
lv_coord_t line_height; /**< The real line height where any text fits*/
|
||||
lv_coord_t base_line; /**< Base line measured from the top of the line_height*/
|
||||
uint8_t subpx : 2; /**< An element of `lv_font_subpx_t`*/
|
||||
|
||||
int8_t underline_position; /**< Distance between the top of the underline and base line (< 0 means below the base line)*/
|
||||
int8_t underline_thickness; /**< Thickness of the underline*/
|
||||
|
||||
void * dsc; /**< Store implementation specific or run_time data or caching here*/
|
||||
#if LV_USE_USER_DATA
|
||||
lv_font_user_data_t user_data; /**< Custom user data for font. */
|
||||
@@ -171,6 +175,10 @@ LV_FONT_DECLARE(lv_font_montserrat_30)
|
||||
LV_FONT_DECLARE(lv_font_montserrat_32)
|
||||
#endif
|
||||
|
||||
#if LV_FONT_MONTSERRAT_34
|
||||
LV_FONT_DECLARE(lv_font_montserrat_34)
|
||||
#endif
|
||||
|
||||
#if LV_FONT_MONTSERRAT_36
|
||||
LV_FONT_DECLARE(lv_font_montserrat_36)
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
CSRCS += lv_font.c
|
||||
CSRCS += lv_font_fmt_txt.c
|
||||
CSRCS += lv_font_loader.c
|
||||
CSRCS += lv_font_montserrat_12.c
|
||||
CSRCS += lv_font_montserrat_14.c
|
||||
CSRCS += lv_font_montserrat_16.c
|
||||
@@ -22,7 +23,7 @@ CSRCS += lv_font_montserrat_48.c
|
||||
CSRCS += lv_font_montserrat_12_subpx.c
|
||||
CSRCS += lv_font_montserrat_28_compressed.c
|
||||
CSRCS += lv_font_unscii_8.c
|
||||
CSRCS += lv_font_ap_18.c
|
||||
CSRCS += lv_font_dejavu_16_persian_hebrew.c
|
||||
|
||||
DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/lv_font
|
||||
VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/lv_font
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*********************/
|
||||
#include "lv_font.h"
|
||||
#include "lv_font_fmt_txt.h"
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "../lv_misc/lv_debug.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
#include "../lv_misc/lv_types.h"
|
||||
#include "../lv_misc/lv_log.h"
|
||||
@@ -37,17 +37,17 @@ static int32_t unicode_list_compare(const void * ref, const void * element);
|
||||
static int32_t kern_pair_8_compare(const void * ref, const void * element);
|
||||
static int32_t kern_pair_16_compare(const void * ref, const void * element);
|
||||
|
||||
static void decompress(const uint8_t * in, uint8_t * out, lv_coord_t w, lv_coord_t h, uint8_t bpp);
|
||||
static void decompress(const uint8_t * in, uint8_t * out, lv_coord_t w, lv_coord_t h, uint8_t bpp, bool prefilter);
|
||||
static inline void decompress_line(uint8_t * out, lv_coord_t w);
|
||||
static inline uint8_t get_bits(const uint8_t * in, uint32_t bit_pos, uint8_t len);
|
||||
static inline void bits_write(uint8_t * out, uint32_t bit_pos, uint8_t val, uint8_t len);
|
||||
static inline void rle_init(const uint8_t * in, uint8_t bpp);
|
||||
static inline uint8_t rle_next(void);
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
static uint8_t * decompr_buf;
|
||||
static uint32_t rle_rdp;
|
||||
static const uint8_t * rle_in;
|
||||
static uint8_t rle_bpp;
|
||||
@@ -88,19 +88,40 @@ const uint8_t * lv_font_get_bitmap_fmt_txt(const lv_font_t * font, uint32_t unic
|
||||
}
|
||||
/*Handle compressed bitmap*/
|
||||
else {
|
||||
static uint8_t * buf = NULL;
|
||||
|
||||
#if LV_USE_FONT_COMPRESSED
|
||||
uint32_t gsize = gdsc->box_w * gdsc->box_h;
|
||||
if(gsize == 0) return NULL;
|
||||
|
||||
if(lv_mem_get_size(buf) < gsize) {
|
||||
buf = lv_mem_realloc(buf, gsize);
|
||||
LV_ASSERT_MEM(buf);
|
||||
if(buf == NULL) return NULL;
|
||||
uint32_t buf_size = gsize;
|
||||
/*Compute memory size needed to hold decompressed glyph, rounding up*/
|
||||
switch(fdsc->bpp) {
|
||||
case 1:
|
||||
buf_size = (gsize + 7) >> 3;
|
||||
break;
|
||||
case 2:
|
||||
buf_size = (gsize + 3) >> 2;
|
||||
break;
|
||||
case 3:
|
||||
buf_size = (gsize + 1) >> 1;
|
||||
break;
|
||||
case 4:
|
||||
buf_size = (gsize + 1) >> 1;
|
||||
break;
|
||||
}
|
||||
|
||||
decompress(&fdsc->glyph_bitmap[gdsc->bitmap_index], buf, gdsc->box_w, gdsc->box_h, (uint8_t)fdsc->bpp);
|
||||
return buf;
|
||||
if(_lv_mem_get_size(decompr_buf) < buf_size) {
|
||||
decompr_buf = lv_mem_realloc(decompr_buf, buf_size);
|
||||
LV_ASSERT_MEM(decompr_buf);
|
||||
if(decompr_buf == NULL) return NULL;
|
||||
}
|
||||
|
||||
bool prefilter = fdsc->bitmap_format == LV_FONT_FMT_TXT_COMPRESSED ? true : false;
|
||||
decompress(&fdsc->glyph_bitmap[gdsc->bitmap_index], decompr_buf, gdsc->box_w, gdsc->box_h, (uint8_t)fdsc->bpp,
|
||||
prefilter);
|
||||
return decompr_buf;
|
||||
#else /* !LV_USE_FONT_COMPRESSED */
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*If not returned earlier then the letter is not found in this font*/
|
||||
@@ -151,13 +172,25 @@ bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_glyph_dsc_t *
|
||||
dsc_out->box_w = gdsc->box_w;
|
||||
dsc_out->ofs_x = gdsc->ofs_x;
|
||||
dsc_out->ofs_y = gdsc->ofs_y;
|
||||
dsc_out->bpp = fdsc->bitmap_format == LV_FONT_FMT_TXT_PLAIN ? (uint8_t)fdsc->bpp : 8;
|
||||
dsc_out->bpp = (uint8_t)fdsc->bpp;
|
||||
|
||||
if(is_tab) dsc_out->box_w = dsc_out->box_w * 2;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free the allocated memories.
|
||||
*/
|
||||
void _lv_font_clean_up_fmt_txt(void)
|
||||
{
|
||||
if(decompr_buf) {
|
||||
lv_mem_free(decompr_buf);
|
||||
decompr_buf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
@@ -186,8 +219,9 @@ static uint32_t get_glyph_dsc_id(const lv_font_t * font, uint32_t letter)
|
||||
glyph_id = fdsc->cmaps[i].glyph_id_start + gid_ofs_8[rcp];
|
||||
}
|
||||
else if(fdsc->cmaps[i].type == LV_FONT_FMT_TXT_CMAP_SPARSE_TINY) {
|
||||
uint8_t * p = lv_utils_bsearch(&rcp, fdsc->cmaps[i].unicode_list, fdsc->cmaps[i].list_length,
|
||||
sizeof(fdsc->cmaps[i].unicode_list[0]), unicode_list_compare);
|
||||
uint16_t key = rcp;
|
||||
uint8_t * p = _lv_utils_bsearch(&key, fdsc->cmaps[i].unicode_list, fdsc->cmaps[i].list_length,
|
||||
sizeof(fdsc->cmaps[i].unicode_list[0]), unicode_list_compare);
|
||||
|
||||
if(p) {
|
||||
lv_uintptr_t ofs = (lv_uintptr_t)(p - (uint8_t *) fdsc->cmaps[i].unicode_list);
|
||||
@@ -196,8 +230,9 @@ static uint32_t get_glyph_dsc_id(const lv_font_t * font, uint32_t letter)
|
||||
}
|
||||
}
|
||||
else if(fdsc->cmaps[i].type == LV_FONT_FMT_TXT_CMAP_SPARSE_FULL) {
|
||||
uint8_t * p = lv_utils_bsearch(&rcp, fdsc->cmaps[i].unicode_list, fdsc->cmaps[i].list_length,
|
||||
sizeof(fdsc->cmaps[i].unicode_list[0]), unicode_list_compare);
|
||||
uint16_t key = rcp;
|
||||
uint8_t * p = _lv_utils_bsearch(&key, fdsc->cmaps[i].unicode_list, fdsc->cmaps[i].list_length,
|
||||
sizeof(fdsc->cmaps[i].unicode_list[0]), unicode_list_compare);
|
||||
|
||||
if(p) {
|
||||
lv_uintptr_t ofs = (lv_uintptr_t)(p - (uint8_t *) fdsc->cmaps[i].unicode_list);
|
||||
@@ -233,7 +268,7 @@ static int8_t get_kern_value(const lv_font_t * font, uint32_t gid_left, uint32_t
|
||||
* The pairs are ordered left_id first, then right_id secondly. */
|
||||
const uint8_t * g_ids = kdsc->glyph_ids;
|
||||
uint16_t g_id_both = (gid_right << 8) + gid_left; /*Create one number from the ids*/
|
||||
uint8_t * kid_p = lv_utils_bsearch(&g_id_both, g_ids, kdsc->pair_cnt, 2, kern_pair_8_compare);
|
||||
uint8_t * kid_p = _lv_utils_bsearch(&g_id_both, g_ids, kdsc->pair_cnt, 2, kern_pair_8_compare);
|
||||
|
||||
/*If the `g_id_both` were found get its index from the pointer*/
|
||||
if(kid_p) {
|
||||
@@ -247,7 +282,7 @@ static int8_t get_kern_value(const lv_font_t * font, uint32_t gid_left, uint32_t
|
||||
* The pairs are ordered left_id first, then right_id secondly. */
|
||||
const uint16_t * g_ids = kdsc->glyph_ids;
|
||||
lv_uintptr_t g_id_both = (uint32_t)((uint32_t)gid_right << 8) + gid_left; /*Create one number from the ids*/
|
||||
uint8_t * kid_p = lv_utils_bsearch(&g_id_both, g_ids, kdsc->pair_cnt, 4, kern_pair_16_compare);
|
||||
uint8_t * kid_p = _lv_utils_bsearch(&g_id_both, g_ids, kdsc->pair_cnt, 4, kern_pair_16_compare);
|
||||
|
||||
/*If the `g_id_both` were found get its index from the pointer*/
|
||||
if(kid_p) {
|
||||
@@ -304,35 +339,23 @@ static int32_t kern_pair_16_compare(const void * ref, const void * element)
|
||||
* @param out buffer to store the result
|
||||
* @param px_num number of pixels in the glyph (width * height)
|
||||
* @param bpp bit per pixel (bpp = 3 will be converted to bpp = 4)
|
||||
* @param prefilter true: the lines are XORed
|
||||
*/
|
||||
static void decompress(const uint8_t * in, uint8_t * out, lv_coord_t w, lv_coord_t h, uint8_t bpp)
|
||||
static void decompress(const uint8_t * in, uint8_t * out, lv_coord_t w, lv_coord_t h, uint8_t bpp, bool prefilter)
|
||||
{
|
||||
uint32_t wrp = 0;
|
||||
uint8_t wr_size = bpp;
|
||||
if(bpp == 3) wr_size = 4;
|
||||
|
||||
rle_init(in, bpp);
|
||||
|
||||
const uint8_t * bpp_opa_table;
|
||||
switch(bpp) {
|
||||
case 1:
|
||||
bpp_opa_table = _lv_bpp1_opa_table;
|
||||
break;
|
||||
case 2:
|
||||
bpp_opa_table = _lv_bpp2_opa_table;
|
||||
break;
|
||||
case 3:
|
||||
bpp_opa_table = _lv_bpp3_opa_table;
|
||||
break;
|
||||
case 4:
|
||||
bpp_opa_table = _lv_bpp4_opa_table;
|
||||
break;
|
||||
case 8:
|
||||
bpp_opa_table = _lv_bpp8_opa_table;
|
||||
break;
|
||||
default:
|
||||
LV_LOG_WARN("Invalid bpp (%d)", bpp);
|
||||
return;
|
||||
}
|
||||
uint8_t * line_buf1 = _lv_mem_buf_get(w);
|
||||
|
||||
uint8_t * line_buf1 = lv_mem_buf_get(w);
|
||||
uint8_t * line_buf2 = lv_mem_buf_get(w);
|
||||
uint8_t * line_buf2 = NULL;
|
||||
|
||||
if(prefilter) {
|
||||
line_buf2 = _lv_mem_buf_get(w);
|
||||
}
|
||||
|
||||
decompress_line(line_buf1, w);
|
||||
|
||||
@@ -340,22 +363,32 @@ static void decompress(const uint8_t * in, uint8_t * out, lv_coord_t w, lv_coord
|
||||
lv_coord_t x;
|
||||
|
||||
for(x = 0; x < w; x++) {
|
||||
*out = bpp_opa_table[line_buf1[x]];
|
||||
out++;
|
||||
bits_write(out, wrp, line_buf1[x], bpp);
|
||||
wrp += wr_size;
|
||||
}
|
||||
|
||||
for(y = 1; y < h; y++) {
|
||||
decompress_line(line_buf2, w);
|
||||
if(prefilter) {
|
||||
decompress_line(line_buf2, w);
|
||||
|
||||
for(x = 0; x < w; x++) {
|
||||
line_buf1[x] = line_buf2[x] ^ line_buf1[x];
|
||||
*out = bpp_opa_table[line_buf1[x]];
|
||||
out++;
|
||||
for(x = 0; x < w; x++) {
|
||||
line_buf1[x] = line_buf2[x] ^ line_buf1[x];
|
||||
bits_write(out, wrp, line_buf1[x], bpp);
|
||||
wrp += wr_size;
|
||||
}
|
||||
}
|
||||
else {
|
||||
decompress_line(line_buf1, w);
|
||||
|
||||
for(x = 0; x < w; x++) {
|
||||
bits_write(out, wrp, line_buf1[x], bpp);
|
||||
wrp += wr_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lv_mem_buf_release(line_buf1);
|
||||
lv_mem_buf_release(line_buf2);
|
||||
_lv_mem_buf_release(line_buf1);
|
||||
_lv_mem_buf_release(line_buf2);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -374,7 +407,7 @@ static inline void decompress_line(uint8_t * out, lv_coord_t w)
|
||||
/**
|
||||
* Read bits from an input buffer. The read can cross byte boundary.
|
||||
* @param in the input buffer to read from.
|
||||
* @param bit_pos index of teh first bit to read.
|
||||
* @param bit_pos index of the first bit to read.
|
||||
* @param len number of bits to read (must be <= 8).
|
||||
* @return the read bits
|
||||
*/
|
||||
@@ -413,6 +446,55 @@ static inline uint8_t get_bits(const uint8_t * in, uint32_t bit_pos, uint8_t len
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write `val` data to `bit_pos` position of `out`. The write can NOT cross byte boundary.
|
||||
* @param out buffer where to write
|
||||
* @param bit_pos bit index to write
|
||||
* @param val value to write
|
||||
* @param len length of bits to write from `val`. (Counted from the LSB).
|
||||
* @note `len == 3` will be converted to `len = 4` and `val` will be upscaled too
|
||||
*/
|
||||
static inline void bits_write(uint8_t * out, uint32_t bit_pos, uint8_t val, uint8_t len)
|
||||
{
|
||||
if(len == 3) {
|
||||
len = 4;
|
||||
switch(val) {
|
||||
case 0:
|
||||
val = 0;
|
||||
break;
|
||||
case 1:
|
||||
val = 2;
|
||||
break;
|
||||
case 2:
|
||||
val = 4;
|
||||
break;
|
||||
case 3:
|
||||
val = 6;
|
||||
break;
|
||||
case 4:
|
||||
val = 9;
|
||||
break;
|
||||
case 5:
|
||||
val = 11;
|
||||
break;
|
||||
case 6:
|
||||
val = 13;
|
||||
break;
|
||||
case 7:
|
||||
val = 15;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t byte_pos = bit_pos >> 3;
|
||||
bit_pos = bit_pos & 0x7;
|
||||
bit_pos = 8 - bit_pos - len;
|
||||
|
||||
uint8_t bit_mask = (uint16_t)((uint16_t) 1 << len) - 1;
|
||||
out[byte_pos] &= ((~bit_mask) << bit_pos);
|
||||
out[byte_pos] |= (val << bit_pos);
|
||||
}
|
||||
|
||||
static inline void rle_init(const uint8_t * in, uint8_t bpp)
|
||||
{
|
||||
rle_in = in;
|
||||
|
||||
@@ -59,7 +59,7 @@ typedef uint8_t lv_font_fmt_txt_cmap_type_t;
|
||||
|
||||
/* Map codepoints to a `glyph_dsc`s
|
||||
* Several formats are supported to optimize memory usage
|
||||
* See https://github.com/littlevgl/lv_font_conv/blob/master/doc/font_spec.md
|
||||
* See https://github.com/lvgl/lv_font_conv/blob/master/doc/font_spec.md
|
||||
*/
|
||||
typedef struct {
|
||||
/** First Unicode character for this range */
|
||||
@@ -74,7 +74,7 @@ typedef struct {
|
||||
|
||||
/*
|
||||
According the specification there are 4 formats:
|
||||
https://github.com/littlevgl/lv_font_conv/blob/master/doc/font_spec.md
|
||||
https://github.com/lvgl/lv_font_conv/blob/master/doc/font_spec.md
|
||||
|
||||
For simplicity introduce "relative code point":
|
||||
rcp = codepoint - range_start
|
||||
@@ -135,7 +135,7 @@ typedef struct {
|
||||
2 Get the class of the left and right glyphs as `left_class` and `right_class`
|
||||
left_class = left_class_mapping[glyph_id_left];
|
||||
right_class = right_class_mapping[glyph_id_right];
|
||||
3. value = class_pair_values[(left_class-1)*right_class_cnt + (righ_class-1)]
|
||||
3. value = class_pair_values[(left_class-1)*right_class_cnt + (right_class-1)]
|
||||
*/
|
||||
|
||||
const int8_t * class_pair_values; /*left_class_num * right_class_num value*/
|
||||
@@ -150,12 +150,13 @@ typedef struct {
|
||||
typedef enum {
|
||||
LV_FONT_FMT_TXT_PLAIN = 0,
|
||||
LV_FONT_FMT_TXT_COMPRESSED = 1,
|
||||
LV_FONT_FMT_TXT_COMPRESSED_NO_PREFILTER = 1,
|
||||
} lv_font_fmt_txt_bitmap_format_t;
|
||||
|
||||
|
||||
/*Describe store additional data for fonts */
|
||||
typedef struct {
|
||||
/*The bitmaps os all glyphs*/
|
||||
/*The bitmaps of all glyphs*/
|
||||
const uint8_t * glyph_bitmap;
|
||||
|
||||
/*Describe the glyphs*/
|
||||
@@ -218,6 +219,11 @@ const uint8_t * lv_font_get_bitmap_fmt_txt(const lv_font_t * font, uint32_t lett
|
||||
bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter,
|
||||
uint32_t unicode_letter_next);
|
||||
|
||||
/**
|
||||
* Free the allocated memories.
|
||||
*/
|
||||
void _lv_font_clean_up_fmt_txt(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
694
src/lv_font/lv_font_loader.c
Normal file
694
src/lv_font/lv_font_loader.c
Normal file
@@ -0,0 +1,694 @@
|
||||
/**
|
||||
* @file lv_font_loader.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "../lvgl.h"
|
||||
#include "../lv_misc/lv_fs.h"
|
||||
#include "lv_font_loader.h"
|
||||
|
||||
#if LV_USE_FILESYSTEM
|
||||
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef struct {
|
||||
lv_fs_file_t * fp;
|
||||
int8_t bit_pos;
|
||||
uint8_t byte_value;
|
||||
} bit_iterator_t;
|
||||
|
||||
typedef struct font_header_bin {
|
||||
uint32_t version;
|
||||
uint16_t tables_count;
|
||||
uint16_t font_size;
|
||||
uint16_t ascent;
|
||||
int16_t descent;
|
||||
uint16_t typo_ascent;
|
||||
int16_t typo_descent;
|
||||
uint16_t typo_line_gap;
|
||||
int16_t min_y;
|
||||
int16_t max_y;
|
||||
uint16_t default_advance_width;
|
||||
uint16_t kerning_scale;
|
||||
uint8_t index_to_loc_format;
|
||||
uint8_t glyph_id_format;
|
||||
uint8_t advance_width_format;
|
||||
uint8_t bits_per_pixel;
|
||||
uint8_t xy_bits;
|
||||
uint8_t wh_bits;
|
||||
uint8_t advance_width_bits;
|
||||
uint8_t compression_id;
|
||||
uint8_t subpixels_mode;
|
||||
uint8_t padding;
|
||||
} font_header_bin_t;
|
||||
|
||||
typedef struct cmap_table_bin {
|
||||
uint32_t data_offset;
|
||||
uint32_t range_start;
|
||||
uint16_t range_length;
|
||||
uint16_t glyph_id_start;
|
||||
uint16_t data_entries_count;
|
||||
uint8_t format_type;
|
||||
uint8_t padding;
|
||||
} cmap_table_bin_t;
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static bit_iterator_t init_bit_iterator(lv_fs_file_t * fp);
|
||||
static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font);
|
||||
int32_t load_kern(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc, uint8_t format, uint32_t start);
|
||||
|
||||
static int read_bits_signed(bit_iterator_t * it, int n_bits, lv_fs_res_t * res);
|
||||
static int read_bits(bit_iterator_t * it, int n_bits, lv_fs_res_t * res);
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Loads a `lv_font_t` object from a binary font file
|
||||
* @param font_name filename where the font file is located
|
||||
* @return a pointer to the font or NULL in case of error
|
||||
*/
|
||||
lv_font_t * lv_font_load(const char * font_name)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
lv_font_t * font = lv_mem_alloc(sizeof(lv_font_t));
|
||||
memset(font, 0, sizeof(lv_font_t));
|
||||
|
||||
lv_fs_file_t file;
|
||||
lv_fs_res_t res = lv_fs_open(&file, font_name, LV_FS_MODE_RD);
|
||||
|
||||
if(res == LV_FS_RES_OK) {
|
||||
success = lvgl_load_font(&file, font);
|
||||
}
|
||||
|
||||
if(!success) {
|
||||
LV_LOG_WARN("Error loading font file: %s\n", font_name);
|
||||
/*
|
||||
* When `lvgl_load_font` fails it can leak some pointers.
|
||||
* All non-null pointers can be assumed as allocated and
|
||||
* `lv_font_free` should free them correctly.
|
||||
*/
|
||||
lv_font_free(font);
|
||||
font = NULL;
|
||||
}
|
||||
|
||||
lv_fs_close(&file);
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Frees the memory allocated by the `lv_font_load()` function
|
||||
* @param font lv_font_t object created by the lv_font_load function
|
||||
*/
|
||||
void lv_font_free(lv_font_t * font)
|
||||
{
|
||||
if(NULL != font) {
|
||||
lv_font_fmt_txt_dsc_t * dsc = (lv_font_fmt_txt_dsc_t *) font->dsc;
|
||||
|
||||
if(NULL != dsc) {
|
||||
|
||||
if(dsc->kern_classes == 0) {
|
||||
lv_font_fmt_txt_kern_pair_t * kern_dsc =
|
||||
(lv_font_fmt_txt_kern_pair_t *) dsc->kern_dsc;
|
||||
|
||||
if(NULL != kern_dsc) {
|
||||
if(kern_dsc->glyph_ids)
|
||||
lv_mem_free((void *) kern_dsc->glyph_ids);
|
||||
|
||||
if(kern_dsc->values)
|
||||
lv_mem_free((void *) kern_dsc->values);
|
||||
|
||||
lv_mem_free((void *) kern_dsc);
|
||||
}
|
||||
}
|
||||
else {
|
||||
lv_font_fmt_txt_kern_classes_t * kern_dsc =
|
||||
(lv_font_fmt_txt_kern_classes_t *) dsc->kern_dsc;
|
||||
|
||||
if(NULL != kern_dsc) {
|
||||
if(kern_dsc->class_pair_values)
|
||||
lv_mem_free((void *) kern_dsc->class_pair_values);
|
||||
|
||||
if(kern_dsc->left_class_mapping)
|
||||
lv_mem_free((void *) kern_dsc->left_class_mapping);
|
||||
|
||||
if(kern_dsc->right_class_mapping)
|
||||
lv_mem_free((void *) kern_dsc->right_class_mapping);
|
||||
|
||||
lv_mem_free((void *) kern_dsc);
|
||||
}
|
||||
}
|
||||
|
||||
lv_font_fmt_txt_cmap_t * cmaps =
|
||||
(lv_font_fmt_txt_cmap_t *) dsc->cmaps;
|
||||
|
||||
if(NULL != cmaps) {
|
||||
for(int i = 0; i < dsc->cmap_num; ++i) {
|
||||
if(NULL != cmaps[i].glyph_id_ofs_list)
|
||||
lv_mem_free((void *) cmaps[i].glyph_id_ofs_list);
|
||||
if(NULL != cmaps[i].unicode_list)
|
||||
lv_mem_free((void *) cmaps[i].unicode_list);
|
||||
}
|
||||
lv_mem_free(cmaps);
|
||||
}
|
||||
|
||||
if(NULL != dsc->glyph_bitmap) {
|
||||
lv_mem_free((void *) dsc->glyph_bitmap);
|
||||
}
|
||||
if(NULL != dsc->glyph_dsc) {
|
||||
lv_mem_free((void *) dsc->glyph_dsc);
|
||||
}
|
||||
lv_mem_free(dsc);
|
||||
}
|
||||
lv_mem_free(font);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static bit_iterator_t init_bit_iterator(lv_fs_file_t * fp)
|
||||
{
|
||||
bit_iterator_t it;
|
||||
it.fp = fp;
|
||||
it.bit_pos = -1;
|
||||
it.byte_value = 0;
|
||||
return it;
|
||||
}
|
||||
|
||||
static int read_bits(bit_iterator_t * it, int n_bits, lv_fs_res_t * res)
|
||||
{
|
||||
int value = 0;
|
||||
while(n_bits--) {
|
||||
it->byte_value = it->byte_value << 1;
|
||||
it->bit_pos--;
|
||||
|
||||
if(it->bit_pos < 0) {
|
||||
it->bit_pos = 7;
|
||||
*res = lv_fs_read(it->fp, &(it->byte_value), 1, NULL);
|
||||
if(*res != LV_FS_RES_OK) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
int8_t bit = (it->byte_value & 0x80) ? 1 : 0;
|
||||
|
||||
value |= (bit << n_bits);
|
||||
}
|
||||
*res = LV_FS_RES_OK;
|
||||
return value;
|
||||
}
|
||||
|
||||
static int read_bits_signed(bit_iterator_t * it, int n_bits, lv_fs_res_t * res)
|
||||
{
|
||||
int value = read_bits(it, n_bits, res);
|
||||
if(value & (1 << (n_bits - 1))) {
|
||||
for(int bit = n_bits; bit < 8; ++bit) {
|
||||
value |= (1 << bit);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
static int read_label(lv_fs_file_t * fp, int start, const char * label)
|
||||
{
|
||||
lv_fs_seek(fp, start);
|
||||
|
||||
uint32_t length;
|
||||
char buf[4];
|
||||
|
||||
if(lv_fs_read(fp, &length, 4, NULL) != LV_FS_RES_OK
|
||||
|| lv_fs_read(fp, buf, 4, NULL) != LV_FS_RES_OK
|
||||
|| memcmp(label, buf, 4) != 0) {
|
||||
LV_LOG_WARN("Error reading '%s' label.", label);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
static bool load_cmaps_tables(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc,
|
||||
uint32_t cmaps_start, cmap_table_bin_t * cmap_table)
|
||||
{
|
||||
for(unsigned int i = 0; i < font_dsc->cmap_num; ++i) {
|
||||
if(lv_fs_read(fp, &cmap_table[i], sizeof(cmap_table_bin_t), NULL) != LV_FS_RES_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
lv_font_fmt_txt_cmap_t * cmap = (lv_font_fmt_txt_cmap_t *) & (font_dsc->cmaps[i]);
|
||||
|
||||
cmap->range_start = cmap_table[i].range_start;
|
||||
cmap->range_length = cmap_table[i].range_length;
|
||||
cmap->glyph_id_start = cmap_table[i].glyph_id_start;
|
||||
}
|
||||
|
||||
for(unsigned int i = 0; i < font_dsc->cmap_num; ++i) {
|
||||
lv_fs_res_t res = lv_fs_seek(fp, cmaps_start + cmap_table[i].data_offset);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
lv_font_fmt_txt_cmap_t * cmap = (lv_font_fmt_txt_cmap_t *) & (font_dsc->cmaps[i]);
|
||||
|
||||
switch(cmap_table[i].format_type) {
|
||||
case 0: {
|
||||
uint8_t ids_size = sizeof(uint8_t) * cmap_table[i].data_entries_count;
|
||||
uint8_t * glyph_id_ofs_list = lv_mem_alloc(ids_size);
|
||||
|
||||
cmap->glyph_id_ofs_list = glyph_id_ofs_list;
|
||||
|
||||
if(lv_fs_read(fp, glyph_id_ofs_list, ids_size, NULL) != LV_FS_RES_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cmap->type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL;
|
||||
cmap->list_length = cmap->range_length;
|
||||
cmap->unicode_list = NULL;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
cmap->type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY;
|
||||
cmap->list_length = 0;
|
||||
cmap->unicode_list = NULL;
|
||||
cmap->glyph_id_ofs_list = NULL;
|
||||
break;
|
||||
case 1:
|
||||
case 3: {
|
||||
uint32_t list_size = sizeof(uint16_t) * cmap_table[i].data_entries_count;
|
||||
uint16_t * unicode_list = (uint16_t *) lv_mem_alloc(list_size);
|
||||
|
||||
cmap->unicode_list = unicode_list;
|
||||
cmap->list_length = cmap_table[i].data_entries_count;
|
||||
|
||||
if(lv_fs_read(fp, unicode_list, list_size, NULL) != LV_FS_RES_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(cmap_table[i].format_type == 1) {
|
||||
uint16_t * buf = lv_mem_alloc(sizeof(uint16_t) * cmap->list_length);
|
||||
|
||||
cmap->type = LV_FONT_FMT_TXT_CMAP_SPARSE_FULL;
|
||||
cmap->glyph_id_ofs_list = buf;
|
||||
|
||||
if(lv_fs_read(fp, buf, sizeof(uint16_t) * cmap->list_length, NULL) != LV_FS_RES_OK) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
cmap->type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY;
|
||||
cmap->glyph_id_ofs_list = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LV_LOG_WARN("Unknown cmaps format type %d.", cmap_table[i].format_type);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int32_t load_cmaps(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc, uint32_t cmaps_start)
|
||||
{
|
||||
int32_t cmaps_length = read_label(fp, cmaps_start, "cmap");
|
||||
if(cmaps_length < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t cmaps_subtables_count;
|
||||
if(lv_fs_read(fp, &cmaps_subtables_count, sizeof(uint32_t), NULL) != LV_FS_RES_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
lv_font_fmt_txt_cmap_t * cmaps =
|
||||
lv_mem_alloc(cmaps_subtables_count * sizeof(lv_font_fmt_txt_cmap_t));
|
||||
|
||||
memset(cmaps, 0, cmaps_subtables_count * sizeof(lv_font_fmt_txt_cmap_t));
|
||||
|
||||
font_dsc->cmaps = cmaps;
|
||||
font_dsc->cmap_num = cmaps_subtables_count;
|
||||
|
||||
cmap_table_bin_t * cmaps_tables = lv_mem_alloc(sizeof(cmap_table_bin_t) * font_dsc->cmap_num);
|
||||
|
||||
bool success = load_cmaps_tables(fp, font_dsc, cmaps_start, cmaps_tables);
|
||||
|
||||
lv_mem_free(cmaps_tables);
|
||||
|
||||
return success ? cmaps_length : -1;
|
||||
}
|
||||
|
||||
static int32_t load_glyph(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc,
|
||||
uint32_t start, uint32_t * glyph_offset, uint32_t loca_count, font_header_bin_t * header)
|
||||
{
|
||||
int32_t glyph_length = read_label(fp, start, "glyf");
|
||||
if(glyph_length < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
lv_font_fmt_txt_glyph_dsc_t * glyph_dsc = (lv_font_fmt_txt_glyph_dsc_t *)
|
||||
lv_mem_alloc(loca_count * sizeof(lv_font_fmt_txt_glyph_dsc_t));
|
||||
|
||||
memset(glyph_dsc, 0, loca_count * sizeof(lv_font_fmt_txt_glyph_dsc_t));
|
||||
|
||||
font_dsc->glyph_dsc = glyph_dsc;
|
||||
|
||||
int cur_bmp_size = 0;
|
||||
|
||||
for(unsigned int i = 0; i < loca_count; ++i) {
|
||||
lv_font_fmt_txt_glyph_dsc_t * gdsc = &glyph_dsc[i];
|
||||
|
||||
lv_fs_res_t res = lv_fs_seek(fp, start + glyph_offset[i]);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bit_iterator_t bit_it = init_bit_iterator(fp);
|
||||
|
||||
if(header->advance_width_bits == 0) {
|
||||
gdsc->adv_w = header->default_advance_width;
|
||||
}
|
||||
else {
|
||||
gdsc->adv_w = read_bits(&bit_it, header->advance_width_bits, &res);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if(header->advance_width_format == 0) {
|
||||
gdsc->adv_w *= 16;
|
||||
}
|
||||
|
||||
gdsc->ofs_x = read_bits_signed(&bit_it, header->xy_bits, &res);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
gdsc->ofs_y = read_bits_signed(&bit_it, header->xy_bits, &res);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
gdsc->box_w = read_bits(&bit_it, header->wh_bits, &res);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
gdsc->box_h = read_bits(&bit_it, header->wh_bits, &res);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int nbits = header->advance_width_bits + 2 * header->xy_bits + 2 * header->wh_bits;
|
||||
int next_offset = (i < loca_count - 1) ? glyph_offset[i + 1] : (uint32_t)(glyph_length - 1);
|
||||
int bmp_size = next_offset - glyph_offset[i] - nbits / 8;
|
||||
|
||||
if(i == 0) {
|
||||
gdsc->adv_w = 0;
|
||||
gdsc->box_w = 0;
|
||||
gdsc->box_h = 0;
|
||||
gdsc->ofs_x = 0;
|
||||
gdsc->ofs_y = 0;
|
||||
}
|
||||
|
||||
gdsc->bitmap_index = cur_bmp_size;
|
||||
if(gdsc->box_w * gdsc->box_h != 0) {
|
||||
cur_bmp_size += bmp_size;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t * glyph_bmp = (uint8_t *) lv_mem_alloc(sizeof(uint8_t) * cur_bmp_size);
|
||||
|
||||
font_dsc->glyph_bitmap = glyph_bmp;
|
||||
|
||||
cur_bmp_size = 0;
|
||||
|
||||
for(unsigned int i = 1; i < loca_count; ++i) {
|
||||
lv_fs_res_t res = lv_fs_seek(fp, start + glyph_offset[i]);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
return -1;
|
||||
}
|
||||
bit_iterator_t bit_it = init_bit_iterator(fp);
|
||||
|
||||
int nbits = header->advance_width_bits + 2 * header->xy_bits + 2 * header->wh_bits;
|
||||
|
||||
read_bits(&bit_it, nbits, &res);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(glyph_dsc[i].box_w * glyph_dsc[i].box_h == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int next_offset = (i < loca_count - 1) ? glyph_offset[i + 1] : (uint32_t)(glyph_length - 1);
|
||||
int bmp_size = next_offset - glyph_offset[i] - nbits / 8;
|
||||
|
||||
for(int k = 0; k < bmp_size; ++k) {
|
||||
glyph_bmp[cur_bmp_size + k] = read_bits(&bit_it, 8, &res);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
cur_bmp_size += bmp_size;
|
||||
}
|
||||
return glyph_length;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads a `lv_font_t` from a binary file, given a `lv_fs_file_t`.
|
||||
*
|
||||
* Memory allocations on `lvgl_load_font` should be immediately zeroed and
|
||||
* the pointer should be set on the `lv_font_t` data before any possible return.
|
||||
*
|
||||
* When something fails, it returns `false` and the memory on the `lv_font_t`
|
||||
* still needs to be freed using `lv_font_free`.
|
||||
*
|
||||
* `lv_font_free` will assume that all non-null pointers are allocated and
|
||||
* should be freed.
|
||||
*/
|
||||
static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font)
|
||||
{
|
||||
lv_font_fmt_txt_dsc_t * font_dsc = (lv_font_fmt_txt_dsc_t *)
|
||||
lv_mem_alloc(sizeof(lv_font_fmt_txt_dsc_t));
|
||||
|
||||
memset(font_dsc, 0, sizeof(lv_font_fmt_txt_dsc_t));
|
||||
|
||||
font->dsc = font_dsc;
|
||||
|
||||
/* header */
|
||||
int32_t header_length = read_label(fp, 0, "head");
|
||||
if(header_length < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
font_header_bin_t font_header;
|
||||
if(lv_fs_read(fp, &font_header, sizeof(font_header_bin_t), NULL) != LV_FS_RES_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
font->base_line = -font_header.descent;
|
||||
font->line_height = font_header.ascent - font_header.descent;
|
||||
font->get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt;
|
||||
font->get_glyph_bitmap = lv_font_get_bitmap_fmt_txt;
|
||||
font->subpx = LV_FONT_SUBPX_NONE;
|
||||
|
||||
font_dsc->bpp = font_header.bits_per_pixel;
|
||||
font_dsc->kern_scale = font_header.kerning_scale;
|
||||
font_dsc->bitmap_format = font_header.compression_id;
|
||||
|
||||
/* cmaps */
|
||||
uint32_t cmaps_start = header_length;
|
||||
int32_t cmaps_length = load_cmaps(fp, font_dsc, cmaps_start);
|
||||
if(cmaps_length < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* loca */
|
||||
uint32_t loca_start = cmaps_start + cmaps_length;
|
||||
int32_t loca_length = read_label(fp, loca_start, "loca");
|
||||
if(loca_length < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t loca_count;
|
||||
if(lv_fs_read(fp, &loca_count, sizeof(uint32_t), NULL) != LV_FS_RES_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool failed = false;
|
||||
uint32_t * glyph_offset = lv_mem_alloc(sizeof(uint32_t) * (loca_count + 1));
|
||||
|
||||
for(unsigned int i = 0; i < loca_count; ++i) {
|
||||
if(font_header.index_to_loc_format == 0) {
|
||||
uint16_t offset;
|
||||
if(lv_fs_read(fp, &offset, sizeof(uint16_t), NULL) != LV_FS_RES_OK) {
|
||||
failed = true;
|
||||
break;
|
||||
}
|
||||
glyph_offset[i] = offset;
|
||||
}
|
||||
else if(font_header.index_to_loc_format == 1) {
|
||||
uint32_t offset;
|
||||
if(lv_fs_read(fp, &offset, sizeof(uint32_t), NULL) != LV_FS_RES_OK) {
|
||||
failed = true;
|
||||
break;
|
||||
}
|
||||
glyph_offset[i] = offset;
|
||||
}
|
||||
else {
|
||||
LV_LOG_WARN("Unknown index_to_loc_format: %d.", font_header.index_to_loc_format);
|
||||
failed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(failed) {
|
||||
lv_mem_free(glyph_offset);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* glyph */
|
||||
uint32_t glyph_start = loca_start + loca_length;
|
||||
int32_t glyph_length = load_glyph(
|
||||
fp, font_dsc, glyph_start, glyph_offset, loca_count, &font_header);
|
||||
|
||||
lv_mem_free(glyph_offset);
|
||||
|
||||
if(glyph_length < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(font_header.tables_count < 4) {
|
||||
font_dsc->kern_dsc = NULL;
|
||||
font_dsc->kern_classes = 0;
|
||||
font_dsc->kern_scale = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t kern_start = glyph_start + glyph_length;
|
||||
|
||||
int32_t kern_length = load_kern(fp, font_dsc, font_header.glyph_id_format, kern_start);
|
||||
|
||||
return kern_length >= 0;
|
||||
}
|
||||
|
||||
int32_t load_kern(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc, uint8_t format, uint32_t start)
|
||||
{
|
||||
int32_t kern_length = read_label(fp, start, "kern");
|
||||
if(kern_length < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t kern_format_type;
|
||||
int32_t padding;
|
||||
if(lv_fs_read(fp, &kern_format_type, sizeof(uint8_t), NULL) != LV_FS_RES_OK ||
|
||||
lv_fs_read(fp, &padding, 3 * sizeof(uint8_t), NULL) != LV_FS_RES_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(0 == kern_format_type) { /* sorted pairs */
|
||||
lv_font_fmt_txt_kern_pair_t * kern_pair = lv_mem_alloc(sizeof(lv_font_fmt_txt_kern_pair_t));
|
||||
|
||||
memset(kern_pair, 0, sizeof(lv_font_fmt_txt_kern_pair_t));
|
||||
|
||||
font_dsc->kern_dsc = kern_pair;
|
||||
font_dsc->kern_classes = 0;
|
||||
|
||||
uint32_t glyph_entries;
|
||||
if(lv_fs_read(fp, &glyph_entries, sizeof(uint32_t), NULL) != LV_FS_RES_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ids_size;
|
||||
if(format == 0) {
|
||||
ids_size = sizeof(int8_t) * 2 * glyph_entries;
|
||||
}
|
||||
else {
|
||||
ids_size = sizeof(int16_t) * 2 * glyph_entries;
|
||||
}
|
||||
|
||||
uint8_t * glyph_ids = lv_mem_alloc(ids_size);
|
||||
int8_t * values = lv_mem_alloc(glyph_entries);
|
||||
|
||||
kern_pair->glyph_ids_size = format;
|
||||
kern_pair->pair_cnt = glyph_entries;
|
||||
kern_pair->glyph_ids = glyph_ids;
|
||||
kern_pair->values = values;
|
||||
|
||||
if(lv_fs_read(fp, glyph_ids, ids_size, NULL) != LV_FS_RES_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(lv_fs_read(fp, values, glyph_entries, NULL) != LV_FS_RES_OK) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if(3 == kern_format_type) { /* array M*N of classes */
|
||||
|
||||
lv_font_fmt_txt_kern_classes_t * kern_classes = lv_mem_alloc(sizeof(lv_font_fmt_txt_kern_classes_t));
|
||||
|
||||
memset(kern_classes, 0, sizeof(lv_font_fmt_txt_kern_classes_t));
|
||||
|
||||
font_dsc->kern_dsc = kern_classes;
|
||||
font_dsc->kern_classes = 1;
|
||||
|
||||
uint16_t kern_class_mapping_length;
|
||||
uint8_t kern_table_rows;
|
||||
uint8_t kern_table_cols;
|
||||
|
||||
if(lv_fs_read(fp, &kern_class_mapping_length, sizeof(uint16_t), NULL) != LV_FS_RES_OK ||
|
||||
lv_fs_read(fp, &kern_table_rows, sizeof(uint8_t), NULL) != LV_FS_RES_OK ||
|
||||
lv_fs_read(fp, &kern_table_cols, sizeof(uint8_t), NULL) != LV_FS_RES_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int kern_values_length = sizeof(int8_t) * kern_table_rows * kern_table_cols;
|
||||
|
||||
uint8_t * kern_left = lv_mem_alloc(kern_class_mapping_length);
|
||||
uint8_t * kern_right = lv_mem_alloc(kern_class_mapping_length);
|
||||
int8_t * kern_values = lv_mem_alloc(kern_values_length);
|
||||
|
||||
kern_classes->left_class_mapping = kern_left;
|
||||
kern_classes->right_class_mapping = kern_right;
|
||||
kern_classes->left_class_cnt = kern_table_rows;
|
||||
kern_classes->right_class_cnt = kern_table_cols;
|
||||
kern_classes->class_pair_values = kern_values;
|
||||
|
||||
if(lv_fs_read(fp, kern_left, kern_class_mapping_length, NULL) != LV_FS_RES_OK ||
|
||||
lv_fs_read(fp, kern_right, kern_class_mapping_length, NULL) != LV_FS_RES_OK ||
|
||||
lv_fs_read(fp, kern_values, kern_values_length, NULL) != LV_FS_RES_OK) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
LV_LOG_WARN("Unknown kern_format_type: %d", kern_format_type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return kern_length;
|
||||
}
|
||||
|
||||
#endif /*LV_USE_FILESYSTEM*/
|
||||
|
||||
44
src/lv_font/lv_font_loader.h
Normal file
44
src/lv_font/lv_font_loader.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* @file lv_font_loader.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_FONT_LOADER_H
|
||||
#define LV_FONT_LOADER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
#if LV_USE_FILESYSTEM
|
||||
|
||||
lv_font_t * lv_font_load(const char * fontName);
|
||||
void lv_font_free(lv_font_t * font);
|
||||
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_FONT_LOADER_H*/
|
||||
File diff suppressed because one or more lines are too long
@@ -9,7 +9,7 @@ extern "C" {
|
||||
#include "../lv_conf_internal.h"
|
||||
|
||||
/*-------------------------------
|
||||
* Symbols from FontAwsome font
|
||||
* Symbols from FontAwesome font
|
||||
*-----------------------------*/
|
||||
|
||||
/* In the font converter use this list as range:
|
||||
|
||||
@@ -10,28 +10,28 @@
|
||||
#include "../lv_core/lv_refr.h"
|
||||
|
||||
#if LV_USE_GPU_STM32_DMA2D
|
||||
#include "stm32f7xx_hal.h"
|
||||
|
||||
#include LV_GPU_DMA2D_CMSIS_INCLUDE
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#if LV_COLOR_16_SWAP
|
||||
#error "Can't use DMA2D with LV_COLOR_16_SWAP 1"
|
||||
// TODO: F7 has red blue swap bit in control register for all layers and output
|
||||
#error "Can't use DMA2D with LV_COLOR_16_SWAP 1"
|
||||
#endif
|
||||
|
||||
#if LV_COLOR_DEPTH == 8
|
||||
#error "Can't use DMA2D with LV_COLOR_DEPTH == 8"
|
||||
#error "Can't use DMA2D with LV_COLOR_DEPTH == 8"
|
||||
#endif
|
||||
|
||||
#if LV_COLOR_DEPTH == 16
|
||||
#define DMA2D_OUTPUT_FORMAT DMA2D_OUTPUT_RGB565
|
||||
#define DMA2D_INPUT_FORMAT DMA2D_INPUT_RGB565
|
||||
#define LV_DMA2D_COLOR_FORMAT LV_DMA2D_RGB565
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
#define DMA2D_OUTPUT_FORMAT DMA2D_OUTPUT_ARGB8888
|
||||
#define DMA2D_INPUT_FORMAT DMA2D_INPUT_ARGB8888
|
||||
#define LV_DMA2D_COLOR_FORMAT LV_DMA2D_ARGB8888
|
||||
#else
|
||||
/*Can't use GPU with other formats*/
|
||||
/*Can't use GPU with other formats*/
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
@@ -47,7 +47,6 @@ static void dma2d_wait(void);
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static DMA2D_HandleTypeDef hdma2d;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
@@ -57,6 +56,21 @@ static DMA2D_HandleTypeDef hdma2d;
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Turn on the peripheral and set output color mode, this only needs to be done once
|
||||
*/
|
||||
void lv_gpu_stm32_dma2d_init(void)
|
||||
{
|
||||
/* Enable DMA2D clock */
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_DMA2DEN;
|
||||
|
||||
/* Delay after setting peripheral clock */
|
||||
volatile uint32_t temp = RCC->AHB1ENR;
|
||||
|
||||
/* set output colour mode */
|
||||
DMA2D->OPFCCR = LV_DMA2D_COLOR_FORMAT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill an area in the buffer with a color
|
||||
* @param buf a buffer which should be filled
|
||||
@@ -70,18 +84,16 @@ void lv_gpu_stm32_dma2d_fill(lv_color_t * buf, lv_coord_t buf_w, lv_color_t colo
|
||||
{
|
||||
invalidate_cache();
|
||||
|
||||
hdma2d.Instance = DMA2D;
|
||||
hdma2d.Init.Mode = DMA2D_R2M;
|
||||
hdma2d.Init.ColorMode = DMA2D_OUTPUT_FORMAT;
|
||||
hdma2d.Init.OutputOffset = buf_w - fill_w;
|
||||
hdma2d.LayerCfg[1].InputAlpha = DMA2D_NO_MODIF_ALPHA;
|
||||
hdma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_FORMAT;
|
||||
hdma2d.LayerCfg[1].InputOffset = 0;
|
||||
DMA2D->CR = 0x30000;
|
||||
DMA2D->OMAR = (uint32_t)buf;
|
||||
/* as input color mode is same as output we don't need to convert here do we? */
|
||||
DMA2D->OCOLR = color.full;
|
||||
DMA2D->OOR = buf_w - fill_w;
|
||||
DMA2D->NLR = (fill_w << DMA2D_NLR_PL_Pos) | (fill_h << DMA2D_NLR_NL_Pos);
|
||||
|
||||
/* start transfer */
|
||||
DMA2D->CR |= DMA2D_CR_START_Msk;
|
||||
|
||||
/* DMA2D Initialization */
|
||||
HAL_DMA2D_Init(&hdma2d);
|
||||
HAL_DMA2D_ConfigLayer(&hdma2d, 1);
|
||||
HAL_DMA2D_Start(&hdma2d, (uint32_t)lv_color_to32(color), (uint32_t)buf, fill_w, fill_h);
|
||||
dma2d_wait();
|
||||
}
|
||||
|
||||
@@ -96,8 +108,10 @@ void lv_gpu_stm32_dma2d_fill(lv_color_t * buf, lv_coord_t buf_w, lv_color_t colo
|
||||
* @param fill_h height to fill in pixels
|
||||
* @note `buf_w - fill_w` is offset to the next line after fill
|
||||
*/
|
||||
void lv_gpu_stm32_dma2d_fill_mask(lv_color_t * buf, lv_coord_t buf_w, lv_color_t color, const lv_opa_t * mask, lv_opa_t opa, lv_coord_t fill_w, lv_coord_t fill_h)
|
||||
void lv_gpu_stm32_dma2d_fill_mask(lv_color_t * buf, lv_coord_t buf_w, lv_color_t color, const lv_opa_t * mask,
|
||||
lv_opa_t opa, lv_coord_t fill_w, lv_coord_t fill_h)
|
||||
{
|
||||
#if 0
|
||||
invalidate_cache();
|
||||
|
||||
/* Configure the DMA2D Mode, Color Mode and line output offset */
|
||||
@@ -124,8 +138,9 @@ void lv_gpu_stm32_dma2d_fill_mask(lv_color_t * buf, lv_coord_t buf_w, lv_color_t
|
||||
HAL_DMA2D_Init(&hdma2d);
|
||||
HAL_DMA2D_ConfigLayer(&hdma2d, 0);
|
||||
HAL_DMA2D_ConfigLayer(&hdma2d, 1);
|
||||
HAL_DMA2D_BlendingStart(&hdma2d, (uint32_t) mask, (uint32_t) buf, (uint32_t)buf, fill_w, fill_h);
|
||||
HAL_DMA2D_BlendingStart(&hdma2d, (uint32_t) mask, (uint32_t) buf, (uint32_t)buf, fill_w, fill_h);
|
||||
dma2d_wait();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,32 +148,27 @@ void lv_gpu_stm32_dma2d_fill_mask(lv_color_t * buf, lv_coord_t buf_w, lv_color_t
|
||||
* @param buf a buffer where map should be copied
|
||||
* @param buf_w width of the buffer in pixels
|
||||
* @param map an "image" to copy
|
||||
* @param map_w width of teh map in pixels
|
||||
* @param map_w width of the map in pixels
|
||||
* @param copy_w width of the area to copy in pixels (<= buf_w)
|
||||
* @param copy_h height of the area to copy in pixels
|
||||
* @note `map_w - fill_w` is offset to the next line after copy
|
||||
*/
|
||||
void lv_gpu_stm32_dma2d_copy(lv_color_t * buf, lv_coord_t buf_w, const lv_color_t * map, lv_coord_t map_w, lv_coord_t copy_w, lv_coord_t copy_h)
|
||||
void lv_gpu_stm32_dma2d_copy(lv_color_t * buf, lv_coord_t buf_w, const lv_color_t * map, lv_coord_t map_w,
|
||||
lv_coord_t copy_w, lv_coord_t copy_h)
|
||||
{
|
||||
invalidate_cache();
|
||||
|
||||
hdma2d.Instance = DMA2D;
|
||||
hdma2d.Init.Mode = DMA2D_M2M;
|
||||
hdma2d.Init.ColorMode = DMA2D_OUTPUT_FORMAT;
|
||||
hdma2d.Init.OutputOffset = buf_w - copy_w;
|
||||
DMA2D->CR = 0;
|
||||
/* copy output colour mode, this register controls both input and output colour format */
|
||||
DMA2D->FGPFCCR = LV_DMA2D_COLOR_FORMAT;
|
||||
DMA2D->FGMAR = (uint32_t)map;
|
||||
DMA2D->FGOR = map_w - copy_w;
|
||||
DMA2D->OMAR = (uint32_t)buf;
|
||||
DMA2D->OOR = buf_w - copy_w;
|
||||
DMA2D->NLR = (copy_w << DMA2D_NLR_PL_Pos) | (copy_h << DMA2D_NLR_NL_Pos);
|
||||
|
||||
/* Foreground layer */
|
||||
hdma2d.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA;
|
||||
hdma2d.LayerCfg[1].InputAlpha = 0xFF;
|
||||
hdma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_FORMAT;
|
||||
hdma2d.LayerCfg[1].InputOffset = map_w - copy_w;
|
||||
hdma2d.LayerCfg[1].AlphaInverted = DMA2D_REGULAR_ALPHA;
|
||||
|
||||
/* DMA2D Initialization */
|
||||
HAL_DMA2D_Init(&hdma2d);
|
||||
HAL_DMA2D_ConfigLayer(&hdma2d, 0);
|
||||
HAL_DMA2D_ConfigLayer(&hdma2d, 1);
|
||||
HAL_DMA2D_Start(&hdma2d, (uint32_t)map, (uint32_t)buf, copy_w, copy_h);
|
||||
/* start transfer */
|
||||
DMA2D->CR |= DMA2D_CR_START_Msk;
|
||||
dma2d_wait();
|
||||
}
|
||||
|
||||
@@ -168,38 +178,35 @@ void lv_gpu_stm32_dma2d_copy(lv_color_t * buf, lv_coord_t buf_w, const lv_color_
|
||||
* @param buf_w width of the buffer in pixels
|
||||
* @param map an "image" to copy
|
||||
* @param opa opacity of `map`
|
||||
* @param map_w width of teh map in pixels
|
||||
* @param map_w width of the map in pixels
|
||||
* @param copy_w width of the area to copy in pixels (<= buf_w)
|
||||
* @param copy_h height of the area to copy in pixels
|
||||
* @note `map_w - fill_w` is offset to the next line after copy
|
||||
*/
|
||||
void lv_gpu_stm32_dma2d_blend(lv_color_t * buf, lv_coord_t buf_w, const lv_color_t * map, lv_opa_t opa, lv_coord_t map_w, lv_coord_t copy_w, lv_coord_t copy_h)
|
||||
void lv_gpu_stm32_dma2d_blend(lv_color_t * buf, lv_coord_t buf_w, const lv_color_t * map, lv_opa_t opa,
|
||||
lv_coord_t map_w, lv_coord_t copy_w, lv_coord_t copy_h)
|
||||
{
|
||||
invalidate_cache();
|
||||
DMA2D->CR = 0x20000;
|
||||
|
||||
hdma2d.Instance = DMA2D;
|
||||
hdma2d.Init.Mode = DMA2D_M2M_BLEND;
|
||||
hdma2d.Init.ColorMode = DMA2D_OUTPUT_FORMAT;
|
||||
hdma2d.Init.OutputOffset = buf_w - copy_w;
|
||||
DMA2D->BGPFCCR = LV_DMA2D_COLOR_FORMAT;
|
||||
DMA2D->BGMAR = (uint32_t)buf;
|
||||
DMA2D->BGOR = buf_w - copy_w;
|
||||
|
||||
/* Background layer */
|
||||
hdma2d.LayerCfg[0].AlphaMode = DMA2D_NO_MODIF_ALPHA;
|
||||
hdma2d.LayerCfg[0].InputColorMode = DMA2D_INPUT_FORMAT;
|
||||
hdma2d.LayerCfg[0].InputOffset = buf_w - copy_w;
|
||||
hdma2d.LayerCfg[0].AlphaInverted = DMA2D_REGULAR_ALPHA;
|
||||
DMA2D->FGPFCCR = (uint32_t)LV_DMA2D_COLOR_FORMAT
|
||||
/* alpha mode 2, replace with foreground * alpha value */
|
||||
| (2 << DMA2D_FGPFCCR_AM_Pos)
|
||||
/* alpha value */
|
||||
| (opa << DMA2D_FGPFCCR_ALPHA_Pos);
|
||||
DMA2D->FGMAR = (uint32_t)map;
|
||||
DMA2D->FGOR = map_w - copy_w;
|
||||
|
||||
/* Foreground layer */
|
||||
hdma2d.LayerCfg[1].AlphaMode = DMA2D_COMBINE_ALPHA;
|
||||
hdma2d.LayerCfg[1].InputAlpha = opa;
|
||||
hdma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_FORMAT;
|
||||
hdma2d.LayerCfg[1].InputOffset = map_w - copy_w;
|
||||
hdma2d.LayerCfg[1].AlphaInverted = DMA2D_REGULAR_ALPHA;
|
||||
DMA2D->OMAR = (uint32_t)buf;
|
||||
DMA2D->OOR = buf_w - copy_w;
|
||||
DMA2D->NLR = (copy_w << DMA2D_NLR_PL_Pos) | (copy_h << DMA2D_NLR_NL_Pos);
|
||||
|
||||
/* DMA2D Initialization */
|
||||
HAL_DMA2D_Init(&hdma2d);
|
||||
HAL_DMA2D_ConfigLayer(&hdma2d, 0);
|
||||
HAL_DMA2D_ConfigLayer(&hdma2d, 1);
|
||||
HAL_DMA2D_BlendingStart(&hdma2d, (uint32_t)map, (uint32_t)buf, (uint32_t)buf, copy_w, copy_h);
|
||||
/* start transfer */
|
||||
DMA2D->CR |= DMA2D_CR_START_Msk;
|
||||
dma2d_wait();
|
||||
}
|
||||
|
||||
@@ -218,8 +225,8 @@ static void invalidate_cache(void)
|
||||
|
||||
static void dma2d_wait(void)
|
||||
{
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
while(HAL_DMA2D_PollForTransfer(&hdma2d, 0) == HAL_TIMEOUT) {
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
while(DMA2D->CR & DMA2D_CR_START_Msk) {
|
||||
if(disp->driver.wait_cb) disp->driver.wait_cb(&disp->driver);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,12 @@ extern "C" {
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define LV_DMA2D_ARGB8888 0
|
||||
#define LV_DMA2D_RGB888 1
|
||||
#define LV_DMA2D_RGB565 2
|
||||
#define LV_DMA2D_ARGB1555 3
|
||||
#define LV_DMA2D_ARGB4444 4
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
@@ -28,6 +34,11 @@ extern "C" {
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Turn on the peripheral and set output color mode, this only needs to be done once
|
||||
*/
|
||||
void lv_gpu_stm32_dma2d_init(void);
|
||||
|
||||
/**
|
||||
* Fill an area in the buffer with a color
|
||||
* @param buf a buffer which should be filled
|
||||
@@ -37,7 +48,8 @@ extern "C" {
|
||||
* @param fill_h height to fill in pixels
|
||||
* @note `buf_w - fill_w` is offset to the next line after fill
|
||||
*/
|
||||
void lv_gpu_stm32_dma2d_fill(lv_color_t * buf, lv_coord_t buf_w, lv_color_t color, lv_coord_t fill_w, lv_coord_t fill_h);
|
||||
void lv_gpu_stm32_dma2d_fill(lv_color_t * buf, lv_coord_t buf_w, lv_color_t color, lv_coord_t fill_w,
|
||||
lv_coord_t fill_h);
|
||||
|
||||
|
||||
/**
|
||||
@@ -51,31 +63,34 @@ void lv_gpu_stm32_dma2d_fill(lv_color_t * buf, lv_coord_t buf_w, lv_color_t colo
|
||||
* @param fill_h height to fill in pixels
|
||||
* @note `buf_w - fill_w` is offset to the next line after fill
|
||||
*/
|
||||
void lv_gpu_stm32_dma2d_fill_mask(lv_color_t * buf, lv_coord_t buf_w, lv_color_t color, const lv_opa_t * mask, lv_opa_t opa, lv_coord_t fill_w, lv_coord_t fill_h);
|
||||
void lv_gpu_stm32_dma2d_fill_mask(lv_color_t * buf, lv_coord_t buf_w, lv_color_t color, const lv_opa_t * mask,
|
||||
lv_opa_t opa, lv_coord_t fill_w, lv_coord_t fill_h);
|
||||
|
||||
/**
|
||||
* Copy a map (typically RGB image) to a buffer
|
||||
* @param buf a buffer where map should be copied
|
||||
* @param buf_w width of the buffer in pixels
|
||||
* @param map an "image" to copy
|
||||
* @param map_w width of teh map in pixels
|
||||
* @param map_w width of the map in pixels
|
||||
* @param copy_w width of the area to copy in pixels (<= buf_w)
|
||||
* @param copy_h height of the area to copy in pixels
|
||||
* @note `map_w - fill_w` is offset to the next line after copy
|
||||
*/
|
||||
void lv_gpu_stm32_dma2d_copy(lv_color_t * buf, lv_coord_t buf_w, const lv_color_t * map, lv_coord_t map_w, lv_coord_t copy_w, lv_coord_t copy_h);
|
||||
void lv_gpu_stm32_dma2d_copy(lv_color_t * buf, lv_coord_t buf_w, const lv_color_t * map, lv_coord_t map_w,
|
||||
lv_coord_t copy_w, lv_coord_t copy_h);
|
||||
/**
|
||||
* Blend a map (e.g. ARGB image or RGB image with opacity) to a buffer
|
||||
* @param buf a buffer where `map` should be copied
|
||||
* @param buf_w width of the buffer in pixels
|
||||
* @param map an "image" to copy
|
||||
* @param opa opacity of `map`
|
||||
* @param map_w width of teh map in pixels
|
||||
* @param map_w width of the map in pixels
|
||||
* @param copy_w width of the area to copy in pixels (<= buf_w)
|
||||
* @param copy_h height of the area to copy in pixels
|
||||
* @note `map_w - fill_w` is offset to the next line after copy
|
||||
*/
|
||||
void lv_gpu_stm32_dma2d_blend(lv_color_t * buf, lv_coord_t buf_w, const lv_color_t * map, lv_opa_t opa, lv_coord_t map_w, lv_coord_t copy_w, lv_coord_t copy_h);
|
||||
void lv_gpu_stm32_dma2d_blend(lv_color_t * buf, lv_coord_t buf_w, const lv_color_t * map, lv_opa_t opa,
|
||||
lv_coord_t map_w, lv_coord_t copy_w, lv_coord_t copy_h);
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "lv_hal.h"
|
||||
#include "../lv_misc/lv_mem.h"
|
||||
#include "../lv_misc/lv_gc.h"
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "../lv_misc/lv_debug.h"
|
||||
#include "../lv_core/lv_obj.h"
|
||||
#include "../lv_core/lv_refr.h"
|
||||
#include "../lv_themes/lv_theme.h"
|
||||
@@ -56,7 +56,7 @@ static lv_disp_t * disp_def;
|
||||
*/
|
||||
void lv_disp_drv_init(lv_disp_drv_t * driver)
|
||||
{
|
||||
lv_memset_00(driver, sizeof(lv_disp_drv_t));
|
||||
_lv_memset_00(driver, sizeof(lv_disp_drv_t));
|
||||
|
||||
driver->flush_cb = NULL;
|
||||
driver->hor_res = LV_HOR_RES_MAX;
|
||||
@@ -89,7 +89,7 @@ void lv_disp_drv_init(lv_disp_drv_t * driver)
|
||||
/**
|
||||
* Initialize a display buffer
|
||||
* @param disp_buf pointer `lv_disp_buf_t` variable to initialize
|
||||
* @param buf1 A buffer to be used by LittlevGL to draw the image.
|
||||
* @param buf1 A buffer to be used by LVGL to draw the image.
|
||||
* Always has to specified and can't be NULL.
|
||||
* Can be an array allocated by the user. E.g. `static lv_color_t disp_buf1[1024 * 10]`
|
||||
* Or a memory address e.g. in external SRAM
|
||||
@@ -97,13 +97,13 @@ void lv_disp_drv_init(lv_disp_drv_t * driver)
|
||||
* (sending to the display) parallel.
|
||||
* In the `disp_drv->flush` you should use DMA or similar hardware to send
|
||||
* the image to the display in the background.
|
||||
* It lets LittlevGL to render next frame into the other buffer while previous is being
|
||||
* It lets LVGL to render next frame into the other buffer while previous is being
|
||||
* sent. Set to `NULL` if unused.
|
||||
* @param size_in_px_cnt size of the `buf1` and `buf2` in pixel count.
|
||||
*/
|
||||
void lv_disp_buf_init(lv_disp_buf_t * disp_buf, void * buf1, void * buf2, uint32_t size_in_px_cnt)
|
||||
{
|
||||
lv_memset_00(disp_buf, sizeof(lv_disp_buf_t));
|
||||
_lv_memset_00(disp_buf, sizeof(lv_disp_buf_t));
|
||||
|
||||
disp_buf->buf1 = buf1;
|
||||
disp_buf->buf2 = buf2;
|
||||
@@ -119,16 +119,16 @@ void lv_disp_buf_init(lv_disp_buf_t * disp_buf, void * buf1, void * buf2, uint32
|
||||
*/
|
||||
lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
|
||||
{
|
||||
lv_disp_t * disp = lv_ll_ins_head(&LV_GC_ROOT(_lv_disp_ll));
|
||||
lv_disp_t * disp = _lv_ll_ins_head(&LV_GC_ROOT(_lv_disp_ll));
|
||||
if(!disp) {
|
||||
LV_ASSERT_MEM(disp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_memcpy(&disp->driver, driver, sizeof(lv_disp_drv_t));
|
||||
lv_memset_00(&disp->inv_area_joined, sizeof(disp->inv_area_joined));
|
||||
lv_memset_00(&disp->inv_areas, sizeof(disp->inv_areas));
|
||||
lv_ll_init(&disp->scr_ll, sizeof(lv_obj_t));
|
||||
_lv_memset_00(disp, sizeof(lv_disp_t));
|
||||
_lv_memcpy(&disp->driver, driver, sizeof(lv_disp_drv_t));
|
||||
|
||||
_lv_ll_init(&disp->scr_ll, sizeof(lv_obj_t));
|
||||
disp->last_activity_time = 0;
|
||||
|
||||
if(disp_def == NULL) disp_def = disp;
|
||||
@@ -137,13 +137,22 @@ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
|
||||
disp_def = disp; /*Temporarily change the default screen to create the default screens on the
|
||||
new display*/
|
||||
/*Create a refresh task*/
|
||||
disp->refr_task = lv_task_create(lv_disp_refr_task, LV_DISP_DEF_REFR_PERIOD, LV_REFR_TASK_PRIO, disp);
|
||||
disp->refr_task = lv_task_create(_lv_disp_refr_task, LV_DISP_DEF_REFR_PERIOD, LV_REFR_TASK_PRIO, disp);
|
||||
LV_ASSERT_MEM(disp->refr_task);
|
||||
if(disp->refr_task == NULL) return NULL;
|
||||
|
||||
disp->inv_p = 0;
|
||||
disp->last_activity_time = 0;
|
||||
|
||||
disp->bg_color = LV_COLOR_WHITE;
|
||||
disp->bg_img = NULL;
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
disp->bg_opa = LV_OPA_TRANSP;
|
||||
#else
|
||||
disp->bg_opa = LV_OPA_COVER;
|
||||
#endif
|
||||
|
||||
disp->prev_scr = NULL;
|
||||
disp->act_scr = lv_obj_create(NULL, NULL); /*Create a default screen on the display*/
|
||||
disp->top_layer = lv_obj_create(NULL, NULL); /*Create top layer on the display*/
|
||||
disp->sys_layer = lv_obj_create(NULL, NULL); /*Create sys layer on the display*/
|
||||
@@ -158,6 +167,11 @@ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
|
||||
|
||||
lv_task_ready(disp->refr_task); /*Be sure the screen will be refreshed immediately on start up*/
|
||||
|
||||
/*Can't handle this case later so add an error*/
|
||||
if(lv_disp_is_true_double_buf(disp) && disp->driver.set_px_cb) {
|
||||
LV_LOG_ERROR("Can't handle 2 screen sized buffers with set_px_cb. Display will not be refreshed.");
|
||||
}
|
||||
|
||||
return disp;
|
||||
}
|
||||
|
||||
@@ -171,7 +185,7 @@ void lv_disp_drv_update(lv_disp_t * disp, lv_disp_drv_t * new_drv)
|
||||
memcpy(&disp->driver, new_drv, sizeof(lv_disp_drv_t));
|
||||
|
||||
lv_obj_t * scr;
|
||||
LV_LL_READ(disp->scr_ll, scr) {
|
||||
_LV_LL_READ(disp->scr_ll, scr) {
|
||||
lv_obj_set_size(scr, lv_disp_get_hor_res(disp), lv_disp_get_ver_res(disp));
|
||||
}
|
||||
}
|
||||
@@ -195,10 +209,10 @@ void lv_disp_remove(lv_disp_t * disp)
|
||||
indev = lv_indev_get_next(indev);
|
||||
}
|
||||
|
||||
lv_ll_remove(&LV_GC_ROOT(_lv_disp_ll), disp);
|
||||
_lv_ll_remove(&LV_GC_ROOT(_lv_disp_ll), disp);
|
||||
lv_mem_free(disp);
|
||||
|
||||
if(was_default) lv_disp_set_default(lv_ll_get_head(&LV_GC_ROOT(_lv_disp_ll)));
|
||||
if(was_default) lv_disp_set_default(_lv_ll_get_head(&LV_GC_ROOT(_lv_disp_ll)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -257,6 +271,7 @@ lv_coord_t lv_disp_get_ver_res(lv_disp_t * disp)
|
||||
bool lv_disp_get_antialiasing(lv_disp_t * disp)
|
||||
{
|
||||
#if LV_ANTIALIAS == 0
|
||||
LV_UNUSED(disp);
|
||||
return false;
|
||||
#else
|
||||
if(disp == NULL) disp = lv_disp_get_default();
|
||||
@@ -271,10 +286,10 @@ bool lv_disp_get_antialiasing(lv_disp_t * disp)
|
||||
* @param disp pointer to a display (NULL to use the default display)
|
||||
* @return dpi of the display
|
||||
*/
|
||||
uint32_t lv_disp_get_dpi(lv_disp_t * disp)
|
||||
lv_coord_t lv_disp_get_dpi(lv_disp_t * disp)
|
||||
{
|
||||
if(disp == NULL) disp = lv_disp_get_default();
|
||||
if(disp == NULL) return 1; /*Do not return 0 because it might be a divider*/
|
||||
if(disp == NULL) return LV_DPI; /*Do not return 0 because it might be a divider*/
|
||||
return disp->driver.dpi;
|
||||
}
|
||||
|
||||
@@ -286,9 +301,14 @@ uint32_t lv_disp_get_dpi(lv_disp_t * disp)
|
||||
lv_disp_size_t lv_disp_get_size_category(lv_disp_t * disp)
|
||||
{
|
||||
if(disp == NULL) disp = lv_disp_get_default();
|
||||
if(disp == NULL) return LV_DISP_SIZE_SMALL;
|
||||
|
||||
uint32_t w = lv_disp_get_hor_res(disp) * 10 / disp->driver.dpi;
|
||||
uint32_t w;
|
||||
if(disp == NULL) w = LV_HOR_RES_MAX;
|
||||
else w = lv_disp_get_hor_res(disp);
|
||||
|
||||
uint32_t dpi = lv_disp_get_dpi(disp);
|
||||
|
||||
w = w * 10 / dpi;
|
||||
|
||||
if(w < LV_DISP_SMALL_LIMIT) return LV_DISP_SIZE_SMALL;
|
||||
if(w < LV_DISP_MEDIUM_LIMIT) return LV_DISP_SIZE_MEDIUM;
|
||||
@@ -305,7 +325,7 @@ LV_ATTRIBUTE_FLUSH_READY void lv_disp_flush_ready(lv_disp_drv_t * disp_drv)
|
||||
/*If the screen is transparent initialize it when the flushing is ready*/
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
if(disp_drv->screen_transp) {
|
||||
lv_memset_00(disp_drv->buffer->buf_act, disp_drv->buffer->size * sizeof(lv_color32_t));
|
||||
_lv_memset_00(disp_drv->buffer->buf_act, disp_drv->buffer->size * sizeof(lv_color32_t));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -333,9 +353,9 @@ LV_ATTRIBUTE_FLUSH_READY bool lv_disp_flush_is_last(lv_disp_drv_t * disp_drv)
|
||||
lv_disp_t * lv_disp_get_next(lv_disp_t * disp)
|
||||
{
|
||||
if(disp == NULL)
|
||||
return lv_ll_get_head(&LV_GC_ROOT(_lv_disp_ll));
|
||||
return _lv_ll_get_head(&LV_GC_ROOT(_lv_disp_ll));
|
||||
else
|
||||
return lv_ll_get_next(&LV_GC_ROOT(_lv_disp_ll), disp);
|
||||
return _lv_ll_get_next(&LV_GC_ROOT(_lv_disp_ll), disp);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -361,7 +381,7 @@ uint16_t lv_disp_get_inv_buf_size(lv_disp_t * disp)
|
||||
* Pop (delete) the last 'num' invalidated areas from the buffer
|
||||
* @param num number of areas to delete
|
||||
*/
|
||||
void lv_disp_pop_from_inv_buf(lv_disp_t * disp, uint16_t num)
|
||||
void _lv_disp_pop_from_inv_buf(lv_disp_t * disp, uint16_t num)
|
||||
{
|
||||
|
||||
if(disp->inv_p < num)
|
||||
|
||||
@@ -52,10 +52,12 @@ typedef struct {
|
||||
void * buf_act;
|
||||
uint32_t size; /*In pixel count*/
|
||||
lv_area_t area;
|
||||
volatile int flushing; /*1: flushing is in progress. (It can't be a bitfield because when it's cleared from IRQ Read-Modify-Write issue might occur)*/
|
||||
volatile int flushing_last; /*1: It was the last chunk to flush. (It can't be a bitfield because when it's cleared from IRQ Read-Modify-Write issue might occur)*/
|
||||
volatile uint32_t last_area :1; /*1: the last area is being rendered*/
|
||||
volatile uint32_t last_part :1; /*1: the last part of the current area is being rendered*/
|
||||
/*1: flushing is in progress. (It can't be a bit field because when it's cleared from IRQ Read-Modify-Write issue might occur)*/
|
||||
volatile int flushing;
|
||||
/*1: It was the last chunk to flush. (It can't be a bi tfield because when it's cleared from IRQ Read-Modify-Write issue might occur)*/
|
||||
volatile int flushing_last;
|
||||
volatile uint32_t last_area : 1; /*1: the last area is being rendered*/
|
||||
volatile uint32_t last_part : 1; /*1: the last part of the current area is being rendered*/
|
||||
} lv_disp_buf_t;
|
||||
|
||||
/**
|
||||
@@ -67,7 +69,7 @@ typedef struct _disp_drv_t {
|
||||
lv_coord_t ver_res; /**< Vertical resolution. */
|
||||
|
||||
/** Pointer to a buffer initialized with `lv_disp_buf_init()`.
|
||||
* LittlevGL will use this buffer(s) to draw the screens contents */
|
||||
* LVGL will use this buffer(s) to draw the screens contents */
|
||||
lv_disp_buf_t * buffer;
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
@@ -84,7 +86,7 @@ typedef struct _disp_drv_t {
|
||||
/** DPI (dot per inch) of the display.
|
||||
* Set to `LV_DPI` from `lv_Conf.h` by default.
|
||||
*/
|
||||
uint32_t dpi :10;
|
||||
uint32_t dpi : 10;
|
||||
|
||||
/** MANDATORY: Write the internal buffer (VDB) to the display. 'lv_disp_flush_ready()' has to be
|
||||
* called when finished */
|
||||
@@ -144,10 +146,18 @@ typedef struct _disp_t {
|
||||
|
||||
/** Screens of the display*/
|
||||
lv_ll_t scr_ll;
|
||||
struct _lv_obj_t * act_scr; /**< Currently active screen on this display */
|
||||
struct _lv_obj_t * act_scr; /**< Currently active screen on this display */
|
||||
struct _lv_obj_t * prev_scr; /**< Previous screen. Used during screen animations */
|
||||
struct _lv_obj_t * top_layer; /**< @see lv_disp_get_layer_top */
|
||||
struct _lv_obj_t * sys_layer; /**< @see lv_disp_get_layer_sys */
|
||||
|
||||
uint8_t del_prev :
|
||||
1; /**< 1: Automatically delete the previous screen when the screen load animation is ready */
|
||||
|
||||
lv_color_t bg_color; /**< Default display color when screens are transparent*/
|
||||
const void * bg_img; /**< An image source to display as wallpaper*/
|
||||
lv_opa_t bg_opa; /**<Opacity of the background color or wallpaper */
|
||||
|
||||
/** Invalidated (marked to redraw) areas*/
|
||||
lv_area_t inv_areas[LV_INV_BUF_SIZE];
|
||||
uint8_t inv_area_joined[LV_INV_BUF_SIZE];
|
||||
@@ -163,7 +173,7 @@ typedef enum {
|
||||
LV_DISP_SIZE_MEDIUM,
|
||||
LV_DISP_SIZE_LARGE,
|
||||
LV_DISP_SIZE_EXTRA_LARGE,
|
||||
}lv_disp_size_t;
|
||||
} lv_disp_size_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
@@ -180,7 +190,7 @@ void lv_disp_drv_init(lv_disp_drv_t * driver);
|
||||
/**
|
||||
* Initialize a display buffer
|
||||
* @param disp_buf pointer `lv_disp_buf_t` variable to initialize
|
||||
* @param buf1 A buffer to be used by LittlevGL to draw the image.
|
||||
* @param buf1 A buffer to be used by LVGL to draw the image.
|
||||
* Always has to specified and can't be NULL.
|
||||
* Can be an array allocated by the user. E.g. `static lv_color_t disp_buf1[1024 * 10]`
|
||||
* Or a memory address e.g. in external SRAM
|
||||
@@ -188,7 +198,7 @@ void lv_disp_drv_init(lv_disp_drv_t * driver);
|
||||
* (sending to the display) parallel.
|
||||
* In the `disp_drv->flush` you should use DMA or similar hardware to send
|
||||
* the image to the display in the background.
|
||||
* It lets LittlevGL to render next frame into the other buffer while previous is being
|
||||
* It lets LVGL to render next frame into the other buffer while previous is being
|
||||
* sent. Set to `NULL` if unused.
|
||||
* @param size_in_px_cnt size of the `buf1` and `buf2` in pixel count.
|
||||
*/
|
||||
@@ -253,7 +263,7 @@ bool lv_disp_get_antialiasing(lv_disp_t * disp);
|
||||
* @param disp pointer to a display (NULL to use the default display)
|
||||
* @return dpi of the display
|
||||
*/
|
||||
uint32_t lv_disp_get_dpi(lv_disp_t * disp);
|
||||
lv_coord_t lv_disp_get_dpi(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Get the size category of the display based on it's hor. res. and dpi.
|
||||
@@ -304,7 +314,7 @@ uint16_t lv_disp_get_inv_buf_size(lv_disp_t * disp);
|
||||
* Pop (delete) the last 'num' invalidated areas from the buffer
|
||||
* @param num number of areas to delete
|
||||
*/
|
||||
void lv_disp_pop_from_inv_buf(lv_disp_t * disp, uint16_t num);
|
||||
void _lv_disp_pop_from_inv_buf(lv_disp_t * disp, uint16_t num);
|
||||
|
||||
/**
|
||||
* Check the driver configuration if it's double buffered (both `buf1` and `buf2` are set)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "../lv_misc/lv_debug.h"
|
||||
#include "../lv_hal/lv_hal_indev.h"
|
||||
#include "../lv_core/lv_indev.h"
|
||||
#include "../lv_misc/lv_mem.h"
|
||||
@@ -51,7 +51,7 @@
|
||||
*/
|
||||
void lv_indev_drv_init(lv_indev_drv_t * driver)
|
||||
{
|
||||
lv_memset_00(driver, sizeof(lv_indev_drv_t));
|
||||
_lv_memset_00(driver, sizeof(lv_indev_drv_t));
|
||||
|
||||
driver->type = LV_INDEV_TYPE_NONE;
|
||||
driver->drag_limit = LV_INDEV_DEF_DRAG_LIMIT;
|
||||
@@ -73,26 +73,26 @@ lv_indev_t * lv_indev_drv_register(lv_indev_drv_t * driver)
|
||||
if(driver->disp == NULL) driver->disp = lv_disp_get_default();
|
||||
|
||||
if(driver->disp == NULL) {
|
||||
LV_LOG_WARN("lv_indev_drv_register: no display registered hence can't attache the indev to "
|
||||
LV_LOG_WARN("lv_indev_drv_register: no display registered hence can't attach the indev to "
|
||||
"a display");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_indev_t * indev = lv_ll_ins_head(&LV_GC_ROOT(_lv_indev_ll));
|
||||
lv_indev_t * indev = _lv_ll_ins_head(&LV_GC_ROOT(_lv_indev_ll));
|
||||
if(!indev) {
|
||||
LV_ASSERT_MEM(indev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_memset_00(indev, sizeof(lv_indev_t));
|
||||
lv_memcpy(&indev->driver, driver, sizeof(lv_indev_drv_t));
|
||||
_lv_memset_00(indev, sizeof(lv_indev_t));
|
||||
_lv_memcpy(&indev->driver, driver, sizeof(lv_indev_drv_t));
|
||||
|
||||
indev->proc.reset_query = 1;
|
||||
indev->cursor = NULL;
|
||||
indev->group = NULL;
|
||||
indev->btn_points = NULL;
|
||||
|
||||
indev->driver.read_task = lv_task_create(lv_indev_read_task, LV_INDEV_DEF_READ_PERIOD, LV_TASK_PRIO_HIGH, indev);
|
||||
indev->driver.read_task = lv_task_create(_lv_indev_read_task, LV_INDEV_DEF_READ_PERIOD, LV_TASK_PRIO_HIGH, indev);
|
||||
|
||||
return indev;
|
||||
}
|
||||
@@ -116,9 +116,9 @@ void lv_indev_drv_update(lv_indev_t * indev, lv_indev_drv_t * new_drv)
|
||||
lv_indev_t * lv_indev_get_next(lv_indev_t * indev)
|
||||
{
|
||||
if(indev == NULL)
|
||||
return lv_ll_get_head(&LV_GC_ROOT(_lv_indev_ll));
|
||||
return _lv_ll_get_head(&LV_GC_ROOT(_lv_indev_ll));
|
||||
else
|
||||
return lv_ll_get_next(&LV_GC_ROOT(_lv_indev_ll), indev);
|
||||
return _lv_ll_get_next(&LV_GC_ROOT(_lv_indev_ll), indev);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,11 +127,11 @@ lv_indev_t * lv_indev_get_next(lv_indev_t * indev)
|
||||
* @param data input device will write its data here
|
||||
* @return false: no more data; true: there more data to read (buffered)
|
||||
*/
|
||||
bool lv_indev_read(lv_indev_t * indev, lv_indev_data_t * data)
|
||||
bool _lv_indev_read(lv_indev_t * indev, lv_indev_data_t * data)
|
||||
{
|
||||
bool cont = false;
|
||||
|
||||
lv_memset_00(data, sizeof(lv_indev_data_t));
|
||||
_lv_memset_00(data, sizeof(lv_indev_data_t));
|
||||
|
||||
/* For touchpad sometimes users don't the last pressed coordinate on release.
|
||||
* So be sure a coordinates are initialized to the last point */
|
||||
@@ -143,6 +143,11 @@ bool lv_indev_read(lv_indev_t * indev, lv_indev_data_t * data)
|
||||
else if(indev->driver.type == LV_INDEV_TYPE_KEYPAD) {
|
||||
data->key = indev->proc.types.keypad.last_key;
|
||||
}
|
||||
/*For compatibility assume that used button was enter (encoder push) */
|
||||
else if(indev->driver.type == LV_INDEV_TYPE_ENCODER) {
|
||||
data->key = LV_KEY_ENTER;
|
||||
data->enc_diff = 0;
|
||||
}
|
||||
|
||||
if(indev->driver.read_cb) {
|
||||
LV_LOG_TRACE("idnev read started");
|
||||
|
||||
@@ -137,7 +137,7 @@ typedef struct _lv_indev_proc_t {
|
||||
lv_point_t drag_sum; /*Count the dragged pixels to check LV_INDEV_DEF_DRAG_LIMIT*/
|
||||
lv_point_t drag_throw_vect;
|
||||
struct _lv_obj_t * act_obj; /*The object being pressed*/
|
||||
struct _lv_obj_t * last_obj; /*The last obejct which was pressed (used by dragthrow and
|
||||
struct _lv_obj_t * last_obj; /*The last object which was pressed (used by drag_throw and
|
||||
other post-release event)*/
|
||||
struct _lv_obj_t * last_pressed; /*The lastly pressed object*/
|
||||
|
||||
@@ -220,7 +220,7 @@ lv_indev_t * lv_indev_get_next(lv_indev_t * indev);
|
||||
* @param data input device will write its data here
|
||||
* @return false: no more data; true: there more data to read (buffered)
|
||||
*/
|
||||
bool lv_indev_read(lv_indev_t * indev, lv_indev_data_t * data);
|
||||
bool _lv_indev_read(lv_indev_t * indev, lv_indev_data_t * data);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
||||
@@ -56,12 +56,17 @@ LV_ATTRIBUTE_TICK_INC void lv_tick_inc(uint32_t tick_period)
|
||||
uint32_t lv_tick_get(void)
|
||||
{
|
||||
#if LV_TICK_CUSTOM == 0
|
||||
|
||||
/* If `lv_tick_inc` is called from an interrupt while `sys_time` is read
|
||||
* the result might be corrupted.
|
||||
* This loop detects if `lv_tick_inc` was called while reading `sys_time`.
|
||||
* If `tick_irq_flag` was cleared in `lv_tick_inc` try to read again
|
||||
* until `tick_irq_flag` remains `1`. */
|
||||
uint32_t result;
|
||||
do {
|
||||
tick_irq_flag = 1;
|
||||
result = sys_time;
|
||||
} while(!tick_irq_flag); /*'lv_tick_inc()' clears this flag which can be in an interrupt.
|
||||
Continue until make a non interrupted cycle */
|
||||
} while(!tick_irq_flag); /*Continue until see a non interrupted cycle */
|
||||
|
||||
return result;
|
||||
#else
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#if LV_USE_ANIMATION
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "../lv_misc/lv_debug.h"
|
||||
#include "../lv_hal/lv_hal_tick.h"
|
||||
#include "lv_task.h"
|
||||
#include "lv_math.h"
|
||||
@@ -58,13 +58,13 @@ const lv_anim_path_t lv_anim_path_def = {.cb = lv_anim_path_linear};
|
||||
/**
|
||||
* Init. the animation module
|
||||
*/
|
||||
void lv_anim_core_init(void)
|
||||
void _lv_anim_core_init(void)
|
||||
{
|
||||
lv_ll_init(&LV_GC_ROOT(_lv_anim_ll), sizeof(lv_anim_t));
|
||||
_lv_ll_init(&LV_GC_ROOT(_lv_anim_ll), sizeof(lv_anim_t));
|
||||
last_task_run = lv_tick_get();
|
||||
_lv_anim_task = lv_task_create(anim_task, LV_DISP_DEF_REFR_PERIOD, LV_ANIM_TASK_PRIO, NULL);
|
||||
anim_mark_list_change(); /*Turn off the animation task*/
|
||||
anim_list_changed = false; /*The list has not actaully changed*/
|
||||
anim_list_changed = false; /*The list has not actually changed*/
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,16 +73,15 @@ void lv_anim_core_init(void)
|
||||
* lv_anim_t a;
|
||||
* lv_anim_init(&a);
|
||||
* lv_anim_set_...(&a);
|
||||
* lv_anim_craete(&a);
|
||||
* @param a pointer to an `lv_anim_t` variable to initialize
|
||||
*/
|
||||
void lv_anim_init(lv_anim_t * a)
|
||||
{
|
||||
lv_memset_00(a, sizeof(lv_anim_t));
|
||||
_lv_memset_00(a, sizeof(lv_anim_t));
|
||||
a->time = 500;
|
||||
a->start = 0;
|
||||
a->end = 100;
|
||||
lv_memcpy_small(&a->path, &lv_anim_path_def, sizeof(lv_anim_path_cb_t));
|
||||
_lv_memcpy_small(&a->path, &lv_anim_path_def, sizeof(lv_anim_path_cb_t));
|
||||
a->repeat_cnt = 1;
|
||||
a->early_apply = 1;
|
||||
}
|
||||
@@ -97,22 +96,22 @@ void lv_anim_start(lv_anim_t * a)
|
||||
if(a->exec_cb != NULL) lv_anim_del(a->var, a->exec_cb); /*fp == NULL would delete all animations of var*/
|
||||
|
||||
/*If the list is empty the anim task was suspended and it's last run measure is invalid*/
|
||||
if(lv_ll_is_empty(&LV_GC_ROOT(_lv_anim_ll))) {
|
||||
if(_lv_ll_is_empty(&LV_GC_ROOT(_lv_anim_ll))) {
|
||||
last_task_run = lv_tick_get() - 1;
|
||||
}
|
||||
|
||||
/*Add the new animation to the animation linked list*/
|
||||
lv_anim_t * new_anim = lv_ll_ins_head(&LV_GC_ROOT(_lv_anim_ll));
|
||||
lv_anim_t * new_anim = _lv_ll_ins_head(&LV_GC_ROOT(_lv_anim_ll));
|
||||
LV_ASSERT_MEM(new_anim);
|
||||
if(new_anim == NULL) return;
|
||||
|
||||
/*Initialize the animation descriptor*/
|
||||
a->time_orig = a->time;
|
||||
lv_memcpy(new_anim, a, sizeof(lv_anim_t));
|
||||
_lv_memcpy(new_anim, a, sizeof(lv_anim_t));
|
||||
|
||||
/*Set the start value*/
|
||||
if(new_anim->early_apply) {
|
||||
if(new_anim->exec_cb) new_anim->exec_cb(new_anim->var, new_anim->start);
|
||||
if(new_anim->exec_cb && new_anim->var) new_anim->exec_cb(new_anim->var, new_anim->start);
|
||||
}
|
||||
|
||||
/* Creating an animation changed the linked list.
|
||||
@@ -134,13 +133,13 @@ bool lv_anim_del(void * var, lv_anim_exec_xcb_t exec_cb)
|
||||
lv_anim_t * a;
|
||||
lv_anim_t * a_next;
|
||||
bool del = false;
|
||||
a = lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll));
|
||||
a = _lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll));
|
||||
while(a != NULL) {
|
||||
/*'a' might be deleted, so get the next object while 'a' is valid*/
|
||||
a_next = lv_ll_get_next(&LV_GC_ROOT(_lv_anim_ll), a);
|
||||
a_next = _lv_ll_get_next(&LV_GC_ROOT(_lv_anim_ll), a);
|
||||
|
||||
if(a->var == var && (a->exec_cb == exec_cb || exec_cb == NULL)) {
|
||||
lv_ll_remove(&LV_GC_ROOT(_lv_anim_ll), a);
|
||||
_lv_ll_remove(&LV_GC_ROOT(_lv_anim_ll), a);
|
||||
lv_mem_free(a);
|
||||
anim_mark_list_change(); /*Read by `anim_task`. It need to know if a delete occurred in
|
||||
the linked list*/
|
||||
@@ -163,7 +162,7 @@ bool lv_anim_del(void * var, lv_anim_exec_xcb_t exec_cb)
|
||||
lv_anim_t * lv_anim_get(void * var, lv_anim_exec_xcb_t exec_cb)
|
||||
{
|
||||
lv_anim_t * a;
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_anim_ll), a) {
|
||||
_LV_LL_READ(LV_GC_ROOT(_lv_anim_ll), a) {
|
||||
if(a->var == var && a->exec_cb == exec_cb) {
|
||||
return a;
|
||||
}
|
||||
@@ -180,7 +179,7 @@ uint16_t lv_anim_count_running(void)
|
||||
{
|
||||
uint16_t cnt = 0;
|
||||
lv_anim_t * a;
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_anim_ll), a) cnt++;
|
||||
_LV_LL_READ(LV_GC_ROOT(_lv_anim_ll), a) cnt++;
|
||||
|
||||
return cnt;
|
||||
}
|
||||
@@ -224,6 +223,8 @@ void lv_anim_refr_now(void)
|
||||
*/
|
||||
lv_anim_value_t lv_anim_path_linear(const lv_anim_path_t * path, const lv_anim_t * a)
|
||||
{
|
||||
LV_UNUSED(path);
|
||||
|
||||
/*Calculate the current step*/
|
||||
uint32_t step;
|
||||
if(a->time == a->act_time) {
|
||||
@@ -250,6 +251,8 @@ lv_anim_value_t lv_anim_path_linear(const lv_anim_path_t * path, const lv_anim_t
|
||||
*/
|
||||
lv_anim_value_t lv_anim_path_ease_in(const lv_anim_path_t * path, const lv_anim_t * a)
|
||||
{
|
||||
LV_UNUSED(path);
|
||||
|
||||
/*Calculate the current step*/
|
||||
uint32_t t;
|
||||
if(a->time == a->act_time)
|
||||
@@ -257,7 +260,7 @@ lv_anim_value_t lv_anim_path_ease_in(const lv_anim_path_t * path, const lv_anim_
|
||||
else
|
||||
t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
|
||||
int32_t step = lv_bezier3(t, 0, 1, 1, 1024);
|
||||
int32_t step = _lv_bezier3(t, 0, 1, 1, 1024);
|
||||
|
||||
int32_t new_value;
|
||||
new_value = (int32_t)step * (a->end - a->start);
|
||||
@@ -274,6 +277,8 @@ lv_anim_value_t lv_anim_path_ease_in(const lv_anim_path_t * path, const lv_anim_
|
||||
*/
|
||||
lv_anim_value_t lv_anim_path_ease_out(const lv_anim_path_t * path, const lv_anim_t * a)
|
||||
{
|
||||
LV_UNUSED(path);
|
||||
|
||||
/*Calculate the current step*/
|
||||
|
||||
uint32_t t;
|
||||
@@ -282,7 +287,7 @@ lv_anim_value_t lv_anim_path_ease_out(const lv_anim_path_t * path, const lv_anim
|
||||
else
|
||||
t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
|
||||
int32_t step = lv_bezier3(t, 0, 1023, 1023, 1024);
|
||||
int32_t step = _lv_bezier3(t, 0, 1023, 1023, 1024);
|
||||
|
||||
int32_t new_value;
|
||||
new_value = (int32_t)step * (a->end - a->start);
|
||||
@@ -299,6 +304,8 @@ lv_anim_value_t lv_anim_path_ease_out(const lv_anim_path_t * path, const lv_anim
|
||||
*/
|
||||
lv_anim_value_t lv_anim_path_ease_in_out(const lv_anim_path_t * path, const lv_anim_t * a)
|
||||
{
|
||||
LV_UNUSED(path);
|
||||
|
||||
/*Calculate the current step*/
|
||||
|
||||
uint32_t t;
|
||||
@@ -307,7 +314,7 @@ lv_anim_value_t lv_anim_path_ease_in_out(const lv_anim_path_t * path, const lv_a
|
||||
else
|
||||
t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
|
||||
int32_t step = lv_bezier3(t, 0, 100, 924, 1024);
|
||||
int32_t step = _lv_bezier3(t, 0, 100, 924, 1024);
|
||||
|
||||
int32_t new_value;
|
||||
new_value = (int32_t)step * (a->end - a->start);
|
||||
@@ -324,6 +331,8 @@ lv_anim_value_t lv_anim_path_ease_in_out(const lv_anim_path_t * path, const lv_a
|
||||
*/
|
||||
lv_anim_value_t lv_anim_path_overshoot(const lv_anim_path_t * path, const lv_anim_t * a)
|
||||
{
|
||||
LV_UNUSED(path);
|
||||
|
||||
/*Calculate the current step*/
|
||||
|
||||
uint32_t t;
|
||||
@@ -332,7 +341,7 @@ lv_anim_value_t lv_anim_path_overshoot(const lv_anim_path_t * path, const lv_ani
|
||||
else
|
||||
t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
|
||||
int32_t step = lv_bezier3(t, 0, 1000, 2000, 1024);
|
||||
int32_t step = _lv_bezier3(t, 0, 1000, 2000, 1024);
|
||||
|
||||
int32_t new_value;
|
||||
new_value = (int32_t)step * (a->end - a->start);
|
||||
@@ -350,6 +359,8 @@ lv_anim_value_t lv_anim_path_overshoot(const lv_anim_path_t * path, const lv_ani
|
||||
*/
|
||||
lv_anim_value_t lv_anim_path_bounce(const lv_anim_path_t * path, const lv_anim_t * a)
|
||||
{
|
||||
LV_UNUSED(path);
|
||||
|
||||
/*Calculate the current step*/
|
||||
uint32_t t;
|
||||
if(a->time == a->act_time)
|
||||
@@ -394,7 +405,7 @@ lv_anim_value_t lv_anim_path_bounce(const lv_anim_path_t * path, const lv_anim_t
|
||||
|
||||
if(t > 1024) t = 1024;
|
||||
|
||||
int32_t step = lv_bezier3(t, 1024, 1024, 800, 0);
|
||||
int32_t step = _lv_bezier3(t, 1024, 1024, 800, 0);
|
||||
|
||||
int32_t new_value;
|
||||
new_value = (int32_t)step * diff;
|
||||
@@ -412,6 +423,8 @@ lv_anim_value_t lv_anim_path_bounce(const lv_anim_path_t * path, const lv_anim_t
|
||||
*/
|
||||
lv_anim_value_t lv_anim_path_step(const lv_anim_path_t * path, const lv_anim_t * a)
|
||||
{
|
||||
LV_UNUSED(path);
|
||||
|
||||
if(a->act_time >= a->time)
|
||||
return a->end;
|
||||
else
|
||||
@@ -431,13 +444,13 @@ static void anim_task(lv_task_t * param)
|
||||
(void)param;
|
||||
|
||||
lv_anim_t * a;
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_anim_ll), a) {
|
||||
_LV_LL_READ(LV_GC_ROOT(_lv_anim_ll), a) {
|
||||
a->has_run = 0;
|
||||
}
|
||||
|
||||
uint32_t elaps = lv_tick_elaps(last_task_run);
|
||||
|
||||
a = lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll));
|
||||
a = _lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll));
|
||||
|
||||
while(a != NULL) {
|
||||
/*It can be set by `lv_anim_del()` typically in `end_cb`. If set then an animation delete
|
||||
@@ -462,8 +475,11 @@ static void anim_task(lv_task_t * param)
|
||||
if(a->path.cb) new_value = a->path.cb(&a->path, a);
|
||||
else new_value = lv_anim_path_linear(&a->path, a);
|
||||
|
||||
/*Apply the calculated value*/
|
||||
if(a->exec_cb) a->exec_cb(a->var, new_value);
|
||||
if(new_value != a->current) {
|
||||
a->current = new_value;
|
||||
/*Apply the calculated value*/
|
||||
if(a->exec_cb) a->exec_cb(a->var, new_value);
|
||||
}
|
||||
|
||||
/*If the time is elapsed the animation is ready*/
|
||||
if(a->act_time >= a->time) {
|
||||
@@ -475,9 +491,9 @@ static void anim_task(lv_task_t * param)
|
||||
/* If the linked list changed due to anim. delete then it's not safe to continue
|
||||
* the reading of the list from here -> start from the head*/
|
||||
if(anim_list_changed)
|
||||
a = lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll));
|
||||
a = _lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll));
|
||||
else
|
||||
a = lv_ll_get_next(&LV_GC_ROOT(_lv_anim_ll), a);
|
||||
a = _lv_ll_get_next(&LV_GC_ROOT(_lv_anim_ll), a);
|
||||
}
|
||||
|
||||
last_task_run = lv_tick_get();
|
||||
@@ -487,7 +503,7 @@ static void anim_task(lv_task_t * param)
|
||||
* Called when an animation is ready to do the necessary thinks
|
||||
* e.g. repeat, play back, delete etc.
|
||||
* @param a pointer to an animation descriptor
|
||||
* @return true: animation delete occurred nnd the `LV_GC_ROOT(_lv_anim_ll)` has changed
|
||||
* @return true: animation delete occurred and the `LV_GC_ROOT(_lv_anim_ll)` has changed
|
||||
* */
|
||||
static bool anim_ready_handler(lv_anim_t * a)
|
||||
{
|
||||
@@ -504,8 +520,8 @@ static bool anim_ready_handler(lv_anim_t * a)
|
||||
/*Create copy from the animation and delete the animation from the list.
|
||||
* This way the `ready_cb` will see the animations like it's animation is ready deleted*/
|
||||
lv_anim_t a_tmp;
|
||||
lv_memcpy(&a_tmp, a, sizeof(lv_anim_t));
|
||||
lv_ll_remove(&LV_GC_ROOT(_lv_anim_ll), a);
|
||||
_lv_memcpy(&a_tmp, a, sizeof(lv_anim_t));
|
||||
_lv_ll_remove(&LV_GC_ROOT(_lv_anim_ll), a);
|
||||
lv_mem_free(a);
|
||||
/*Flag that the list has changed */
|
||||
anim_mark_list_change();
|
||||
@@ -515,11 +531,11 @@ static bool anim_ready_handler(lv_anim_t * a)
|
||||
}
|
||||
/*If the animation is not deleted then restart it*/
|
||||
else {
|
||||
a->act_time = -a->repeat_delay; /*Restart the animation*/
|
||||
a->act_time = -(int32_t)(a->repeat_delay); /*Restart the animation*/
|
||||
/*Swap the start and end values in play back mode*/
|
||||
if(a->playback_time != 0) {
|
||||
/*If now turning back use the 'playback_pause*/
|
||||
if(a->playback_now == 0) a->act_time = -a->playback_delay;
|
||||
if(a->playback_now == 0) a->act_time = -(int32_t)(a->playback_delay);
|
||||
|
||||
/*Toggle the play back state*/
|
||||
a->playback_now = a->playback_now == 0 ? 1 : 0;
|
||||
@@ -538,7 +554,7 @@ static bool anim_ready_handler(lv_anim_t * a)
|
||||
static void anim_mark_list_change(void)
|
||||
{
|
||||
anim_list_changed = true;
|
||||
if(lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll)) == NULL)
|
||||
if(_lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll)) == NULL)
|
||||
lv_task_set_prio(_lv_anim_task, LV_TASK_PRIO_OFF);
|
||||
else
|
||||
lv_task_set_prio(_lv_anim_task, LV_ANIM_TASK_PRIO);
|
||||
|
||||
@@ -49,10 +49,10 @@ struct _lv_anim_path_t;
|
||||
/** Get the current value during an animation*/
|
||||
typedef lv_anim_value_t (*lv_anim_path_cb_t)(const struct _lv_anim_path_t *, const struct _lv_anim_t *);
|
||||
|
||||
typedef struct _lv_anim_path_t{
|
||||
typedef struct _lv_anim_path_t {
|
||||
lv_anim_path_cb_t cb;
|
||||
void * user_data;
|
||||
}lv_anim_path_t;
|
||||
} lv_anim_path_t;
|
||||
|
||||
|
||||
|
||||
@@ -82,8 +82,9 @@ typedef struct _lv_anim_t {
|
||||
lv_anim_ready_cb_t ready_cb; /**< Call it when the animation is ready*/
|
||||
lv_anim_path_t path; /**< Describe the path (curve) of animations*/
|
||||
int32_t start; /**< Start value*/
|
||||
int32_t current; /**< Current value */
|
||||
int32_t end; /**< End value*/
|
||||
uint32_t time; /**< Animation time in ms*/
|
||||
int32_t time; /**< Animation time in ms*/
|
||||
int32_t act_time; /**< Current time in animation. Set to negative to make delay.*/
|
||||
uint32_t playback_delay; /**< Wait before play back*/
|
||||
uint32_t playback_time; /**< Duration of playback animation*/
|
||||
@@ -108,7 +109,7 @@ typedef struct _lv_anim_t {
|
||||
/**
|
||||
* Init. the animation module
|
||||
*/
|
||||
void lv_anim_core_init(void);
|
||||
void _lv_anim_core_init(void);
|
||||
|
||||
/**
|
||||
* Initialize an animation variable.
|
||||
@@ -116,7 +117,6 @@ void lv_anim_core_init(void);
|
||||
* lv_anim_t a;
|
||||
* lv_anim_init(&a);
|
||||
* lv_anim_set_...(&a);
|
||||
* lv_anim_create(&a);
|
||||
* @param a pointer to an `lv_anim_t` variable to initialize
|
||||
*/
|
||||
void lv_anim_init(lv_anim_t * a);
|
||||
@@ -160,7 +160,7 @@ static inline void lv_anim_set_time(lv_anim_t * a, uint32_t duration)
|
||||
*/
|
||||
static inline void lv_anim_set_delay(lv_anim_t * a, uint32_t delay)
|
||||
{
|
||||
a->act_time = (int32_t)(-delay);
|
||||
a->act_time = -(int32_t)(delay);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,13 +172,14 @@ static inline void lv_anim_set_delay(lv_anim_t * a, uint32_t delay)
|
||||
static inline void lv_anim_set_values(lv_anim_t * a, lv_anim_value_t start, lv_anim_value_t end)
|
||||
{
|
||||
a->start = start;
|
||||
a->current = start;
|
||||
a->end = end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to `lv_anim_set_exec_cb` but `lv_anim_custom_exec_cb_t` receives
|
||||
* `lv_anim_t * ` as its first parameter instead of `void *`.
|
||||
* This function might be used when LittlevGL is binded to other languages because
|
||||
* This function might be used when LVGL is binded to other languages because
|
||||
* it's more consistent to have `lv_anim_t *` as first parameter.
|
||||
* The variable to animate can be stored in the animation's `user_sata`
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
@@ -198,7 +199,7 @@ static inline void lv_anim_set_custom_exec_cb(lv_anim_t * a, lv_anim_custom_exec
|
||||
*/
|
||||
static inline void lv_anim_set_path(lv_anim_t * a, const lv_anim_path_t * path)
|
||||
{
|
||||
lv_memcpy_small(&a->path, path, sizeof(lv_anim_path_t));
|
||||
_lv_memcpy_small(&a->path, path, sizeof(lv_anim_path_t));
|
||||
}
|
||||
|
||||
|
||||
@@ -274,7 +275,7 @@ void lv_anim_start(lv_anim_t * a);
|
||||
*/
|
||||
static inline void lv_anim_path_init(lv_anim_path_t * path)
|
||||
{
|
||||
lv_memset_00(path, sizeof(lv_anim_path_t));
|
||||
_lv_memset_00(path, sizeof(lv_anim_path_t));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -79,7 +79,7 @@ void lv_area_set_height(lv_area_t * area_p, lv_coord_t h)
|
||||
* @param x the new x coordinate of the area
|
||||
* @param y the new y coordinate of the area
|
||||
*/
|
||||
void lv_area_set_pos(lv_area_t * area_p, lv_coord_t x, lv_coord_t y)
|
||||
void _lv_area_set_pos(lv_area_t * area_p, lv_coord_t x, lv_coord_t y)
|
||||
{
|
||||
lv_coord_t w = lv_area_get_width(area_p);
|
||||
lv_coord_t h = lv_area_get_height(area_p);
|
||||
@@ -110,7 +110,7 @@ uint32_t lv_area_get_size(const lv_area_t * area_p)
|
||||
* @param a2_p pointer to the second area
|
||||
* @return false: the two area has NO common parts, res_p is invalid
|
||||
*/
|
||||
bool lv_area_intersect(lv_area_t * res_p, const lv_area_t * a1_p, const lv_area_t * a2_p)
|
||||
bool _lv_area_intersect(lv_area_t * res_p, const lv_area_t * a1_p, const lv_area_t * a2_p)
|
||||
{
|
||||
/* Get the smaller area from 'a1_p' and 'a2_p' */
|
||||
res_p->x1 = LV_MATH_MAX(a1_p->x1, a2_p->x1);
|
||||
@@ -132,7 +132,7 @@ bool lv_area_intersect(lv_area_t * res_p, const lv_area_t * a1_p, const lv_area_
|
||||
* @param a1_p pointer to the first area
|
||||
* @param a2_p pointer to the second area
|
||||
*/
|
||||
void lv_area_join(lv_area_t * a_res_p, const lv_area_t * a1_p, const lv_area_t * a2_p)
|
||||
void _lv_area_join(lv_area_t * a_res_p, const lv_area_t * a1_p, const lv_area_t * a2_p)
|
||||
{
|
||||
a_res_p->x1 = LV_MATH_MIN(a1_p->x1, a2_p->x1);
|
||||
a_res_p->y1 = LV_MATH_MIN(a1_p->y1, a2_p->y1);
|
||||
@@ -147,7 +147,7 @@ void lv_area_join(lv_area_t * a_res_p, const lv_area_t * a1_p, const lv_area_t *
|
||||
* @param radius radius of area (e.g. for rounded rectangle)
|
||||
* @return false:the point is out of the area
|
||||
*/
|
||||
bool lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p, lv_coord_t radius)
|
||||
bool _lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p, lv_coord_t radius)
|
||||
{
|
||||
/*First check the basic area*/
|
||||
bool is_on_rect = false;
|
||||
@@ -174,7 +174,7 @@ bool lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p, lv_coord
|
||||
corner_area.x2 = a_p->x1 + radius;
|
||||
corner_area.y1 = a_p->y1;
|
||||
corner_area.y2 = a_p->y1 + radius;
|
||||
if(lv_area_is_point_on(&corner_area, p_p, 0)) {
|
||||
if(_lv_area_is_point_on(&corner_area, p_p, 0)) {
|
||||
corner_area.x2 += radius;
|
||||
corner_area.y2 += radius;
|
||||
return lv_point_within_circle(&corner_area, p_p);
|
||||
@@ -182,7 +182,7 @@ bool lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p, lv_coord
|
||||
/*Bottom left*/
|
||||
corner_area.y1 = a_p->y2 - radius;
|
||||
corner_area.y2 = a_p->y2;
|
||||
if(lv_area_is_point_on(&corner_area, p_p, 0)) {
|
||||
if(_lv_area_is_point_on(&corner_area, p_p, 0)) {
|
||||
corner_area.x2 += radius;
|
||||
corner_area.y1 -= radius;
|
||||
return lv_point_within_circle(&corner_area, p_p);
|
||||
@@ -190,7 +190,7 @@ bool lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p, lv_coord
|
||||
/*Bottom right*/
|
||||
corner_area.x1 = a_p->x2 - radius;
|
||||
corner_area.x2 = a_p->x2;
|
||||
if(lv_area_is_point_on(&corner_area, p_p, 0)) {
|
||||
if(_lv_area_is_point_on(&corner_area, p_p, 0)) {
|
||||
corner_area.x1 -= radius;
|
||||
corner_area.y1 -= radius;
|
||||
return lv_point_within_circle(&corner_area, p_p);
|
||||
@@ -198,7 +198,7 @@ bool lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p, lv_coord
|
||||
/*Top right*/
|
||||
corner_area.y1 = a_p->y1;
|
||||
corner_area.y2 = a_p->y1 + radius;
|
||||
if(lv_area_is_point_on(&corner_area, p_p, 0)) {
|
||||
if(_lv_area_is_point_on(&corner_area, p_p, 0)) {
|
||||
corner_area.x1 -= radius;
|
||||
corner_area.y2 += radius;
|
||||
return lv_point_within_circle(&corner_area, p_p);
|
||||
@@ -213,7 +213,7 @@ bool lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p, lv_coord
|
||||
* @param a2_p pointer to an other area
|
||||
* @return false: a1_p and a2_p has no common parts
|
||||
*/
|
||||
bool lv_area_is_on(const lv_area_t * a1_p, const lv_area_t * a2_p)
|
||||
bool _lv_area_is_on(const lv_area_t * a1_p, const lv_area_t * a2_p)
|
||||
{
|
||||
if((a1_p->x1 <= a2_p->x2) && (a1_p->x2 >= a2_p->x1) && (a1_p->y1 <= a2_p->y2) && (a1_p->y2 >= a2_p->y1)) {
|
||||
return true;
|
||||
@@ -230,7 +230,7 @@ bool lv_area_is_on(const lv_area_t * a1_p, const lv_area_t * a2_p)
|
||||
* @param radius radius of `aholder_p` (e.g. for rounded rectangle)
|
||||
* @return true: `ain_p` is fully inside `aholder_p`
|
||||
*/
|
||||
bool lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p, lv_coord_t radius)
|
||||
bool _lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p, lv_coord_t radius)
|
||||
{
|
||||
bool is_in = false;
|
||||
|
||||
@@ -246,36 +246,23 @@ bool lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p, lv_coor
|
||||
|
||||
p.x = ain_p->x1;
|
||||
p.y = ain_p->y1;
|
||||
if(lv_area_is_point_on(aholder_p, &p, radius) == false) return false;
|
||||
if(_lv_area_is_point_on(aholder_p, &p, radius) == false) return false;
|
||||
|
||||
p.x = ain_p->x2;
|
||||
p.y = ain_p->y1;
|
||||
if(lv_area_is_point_on(aholder_p, &p, radius) == false) return false;
|
||||
if(_lv_area_is_point_on(aholder_p, &p, radius) == false) return false;
|
||||
|
||||
p.x = ain_p->x1;
|
||||
p.y = ain_p->y2;
|
||||
if(lv_area_is_point_on(aholder_p, &p, radius) == false) return false;
|
||||
if(_lv_area_is_point_on(aholder_p, &p, radius) == false) return false;
|
||||
|
||||
p.x = ain_p->x2;
|
||||
p.y = ain_p->y2;
|
||||
if(lv_area_is_point_on(aholder_p, &p, radius) == false) return false;
|
||||
if(_lv_area_is_point_on(aholder_p, &p, radius) == false) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment or decrement an area's size by a single amount
|
||||
* @param a_p pointer to an area to grow
|
||||
* @param amount amount to increment the area, or negative to decrement
|
||||
*/
|
||||
void lv_area_increment(lv_area_t * a_p, const lv_coord_t amount)
|
||||
{
|
||||
a_p->x1 -= amount;
|
||||
a_p->y1 -= amount;
|
||||
a_p->x2 += amount;
|
||||
a_p->y2 += amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Align an area to an other
|
||||
* @param base an are where the other will be aligned
|
||||
@@ -283,7 +270,7 @@ void lv_area_increment(lv_area_t * a_p, const lv_coord_t amount)
|
||||
* @param align `LV_ALIGN_...`
|
||||
* @param res x/y coordinates where `to_align` align area should be placed
|
||||
*/
|
||||
void lv_area_align(const lv_area_t * base, const lv_area_t * to_align, lv_align_t align, lv_point_t * res)
|
||||
void _lv_area_align(const lv_area_t * base, const lv_area_t * to_align, lv_align_t align, lv_point_t * res)
|
||||
{
|
||||
|
||||
switch(align) {
|
||||
|
||||
@@ -99,7 +99,7 @@ void lv_area_set(lv_area_t * area_p, lv_coord_t x1, lv_coord_t y1, lv_coord_t x2
|
||||
*/
|
||||
inline static void lv_area_copy(lv_area_t * dest, const lv_area_t * src)
|
||||
{
|
||||
lv_memcpy_small(dest, src, sizeof(lv_area_t));
|
||||
_lv_memcpy_small(dest, src, sizeof(lv_area_t));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,7 +142,7 @@ void lv_area_set_height(lv_area_t * area_p, lv_coord_t h);
|
||||
* @param x the new x coordinate of the area
|
||||
* @param y the new y coordinate of the area
|
||||
*/
|
||||
void lv_area_set_pos(lv_area_t * area_p, lv_coord_t x, lv_coord_t y);
|
||||
void _lv_area_set_pos(lv_area_t * area_p, lv_coord_t x, lv_coord_t y);
|
||||
|
||||
/**
|
||||
* Return with area of an area (x * y)
|
||||
@@ -158,7 +158,7 @@ uint32_t lv_area_get_size(const lv_area_t * area_p);
|
||||
* @param a2_p pointer to the second area
|
||||
* @return false: the two area has NO common parts, res_p is invalid
|
||||
*/
|
||||
bool lv_area_intersect(lv_area_t * res_p, const lv_area_t * a1_p, const lv_area_t * a2_p);
|
||||
bool _lv_area_intersect(lv_area_t * res_p, const lv_area_t * a1_p, const lv_area_t * a2_p);
|
||||
|
||||
/**
|
||||
* Join two areas into a third which involves the other two
|
||||
@@ -166,7 +166,7 @@ bool lv_area_intersect(lv_area_t * res_p, const lv_area_t * a1_p, const lv_area_
|
||||
* @param a1_p pointer to the first area
|
||||
* @param a2_p pointer to the second area
|
||||
*/
|
||||
void lv_area_join(lv_area_t * a_res_p, const lv_area_t * a1_p, const lv_area_t * a2_p);
|
||||
void _lv_area_join(lv_area_t * a_res_p, const lv_area_t * a1_p, const lv_area_t * a2_p);
|
||||
|
||||
/**
|
||||
* Check if a point is on an area
|
||||
@@ -175,7 +175,7 @@ void lv_area_join(lv_area_t * a_res_p, const lv_area_t * a1_p, const lv_area_t *
|
||||
* @param radius radius of area (e.g. for rounded rectangle)
|
||||
* @return false:the point is out of the area
|
||||
*/
|
||||
bool lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p, lv_coord_t radius);
|
||||
bool _lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p, lv_coord_t radius);
|
||||
|
||||
/**
|
||||
* Check if two area has common parts
|
||||
@@ -183,7 +183,7 @@ bool lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p, lv_coord
|
||||
* @param a2_p pointer to an other area
|
||||
* @return false: a1_p and a2_p has no common parts
|
||||
*/
|
||||
bool lv_area_is_on(const lv_area_t * a1_p, const lv_area_t * a2_p);
|
||||
bool _lv_area_is_on(const lv_area_t * a1_p, const lv_area_t * a2_p);
|
||||
|
||||
/**
|
||||
* Check if an area is fully on an other
|
||||
@@ -192,14 +192,8 @@ bool lv_area_is_on(const lv_area_t * a1_p, const lv_area_t * a2_p);
|
||||
* @param radius radius of `aholder_p` (e.g. for rounded rectangle)
|
||||
* @return true: `ain_p` is fully inside `aholder_p`
|
||||
*/
|
||||
bool lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p, lv_coord_t radius);
|
||||
bool _lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p, lv_coord_t radius);
|
||||
|
||||
/**
|
||||
* Increment or decrement an area's size by a single amount
|
||||
* @param a_p pointer to an area to grow
|
||||
* @param amount amount to increment the area, or negative to decrement
|
||||
*/
|
||||
void lv_area_increment(lv_area_t * a_p, const lv_coord_t amount);
|
||||
|
||||
/**
|
||||
* Align an area to an other
|
||||
@@ -208,7 +202,8 @@ void lv_area_increment(lv_area_t * a_p, const lv_coord_t amount);
|
||||
* @param align `LV_ALIGN_...`
|
||||
* @param res x/y coordinates where `to_align` align area should be placed
|
||||
*/
|
||||
void lv_area_align(const lv_area_t * base, const lv_area_t * to_align, lv_align_t align, lv_point_t * res);
|
||||
void _lv_area_align(const lv_area_t * base, const lv_area_t * to_align, lv_align_t align, lv_point_t * res);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
@@ -44,7 +44,7 @@ struct _lv_obj_t;
|
||||
/**
|
||||
* Call an asynchronous function the next time lv_task_handler() is run. This function is likely to return
|
||||
* **before** the call actually happens!
|
||||
* @param task_xcb a callback which is the task itself.
|
||||
* @param async_xcb a callback which is the task itself.
|
||||
* (the 'x' in the argument name indicates that its not a fully generic function because it not follows
|
||||
* the `func_name(object, callback, ...)` convention)
|
||||
* @param user_data custom parameter
|
||||
|
||||
@@ -34,6 +34,13 @@ typedef struct {
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static uint32_t lv_bidi_get_next_paragraph(const char * txt);
|
||||
static lv_bidi_dir_t lv_bidi_get_letter_dir(uint32_t letter);
|
||||
static bool lv_bidi_letter_is_weak(uint32_t letter);
|
||||
static bool lv_bidi_letter_is_rtl(uint32_t letter);
|
||||
static bool lv_bidi_letter_is_neutral(uint32_t letter);
|
||||
|
||||
static lv_bidi_dir_t get_next_run(const char * txt, lv_bidi_dir_t base_dir, uint32_t max_len, uint32_t * len,
|
||||
uint16_t * pos_conv_len);
|
||||
static void rtl_reverse(char * dest, const char * src, uint32_t len, uint16_t * pos_conv_out, uint16_t pos_conv_rd_base,
|
||||
@@ -67,9 +74,9 @@ static uint8_t br_stack_p;
|
||||
* @param str_out store the result here. Has the be `strlen(str_in)` length
|
||||
* @param base_dir `LV_BIDI_DIR_LTR` or `LV_BIDI_DIR_RTL`
|
||||
*/
|
||||
void lv_bidi_process(const char * str_in, char * str_out, lv_bidi_dir_t base_dir)
|
||||
void _lv_bidi_process(const char * str_in, char * str_out, lv_bidi_dir_t base_dir)
|
||||
{
|
||||
if(base_dir == LV_BIDI_DIR_AUTO) base_dir = lv_bidi_detect_base_dir(str_in);
|
||||
if(base_dir == LV_BIDI_DIR_AUTO) base_dir = _lv_bidi_detect_base_dir(str_in);
|
||||
|
||||
uint32_t par_start = 0;
|
||||
uint32_t par_len;
|
||||
@@ -81,7 +88,7 @@ void lv_bidi_process(const char * str_in, char * str_out, lv_bidi_dir_t base_dir
|
||||
|
||||
while(str_in[par_start] != '\0') {
|
||||
par_len = lv_bidi_get_next_paragraph(&str_in[par_start]);
|
||||
lv_bidi_process_paragraph(&str_in[par_start], &str_out[par_start], par_len, base_dir, NULL, 0);
|
||||
_lv_bidi_process_paragraph(&str_in[par_start], &str_out[par_start], par_len, base_dir, NULL, 0);
|
||||
par_start += par_len;
|
||||
|
||||
while(str_in[par_start] == '\n' || str_in[par_start] == '\r') {
|
||||
@@ -98,12 +105,12 @@ void lv_bidi_process(const char * str_in, char * str_out, lv_bidi_dir_t base_dir
|
||||
* @param txt the text to process
|
||||
* @return `LV_BIDI_DIR_LTR` or `LV_BIDI_DIR_RTL`
|
||||
*/
|
||||
lv_bidi_dir_t lv_bidi_detect_base_dir(const char * txt)
|
||||
lv_bidi_dir_t _lv_bidi_detect_base_dir(const char * txt)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
uint32_t letter;
|
||||
while(txt[i] != '\0') {
|
||||
letter = lv_txt_encoded_next(txt, &i);
|
||||
letter = _lv_txt_encoded_next(txt, &i);
|
||||
|
||||
lv_bidi_dir_t dir;
|
||||
dir = lv_bidi_get_letter_dir(letter);
|
||||
@@ -114,71 +121,6 @@ lv_bidi_dir_t lv_bidi_detect_base_dir(const char * txt)
|
||||
if(LV_BIDI_BASE_DIR_DEF == LV_BIDI_DIR_AUTO) return LV_BIDI_DIR_LTR;
|
||||
else return LV_BIDI_BASE_DIR_DEF;
|
||||
}
|
||||
/**
|
||||
* Get the direction of a character
|
||||
* @param letter an Unicode character
|
||||
* @return `LV_BIDI_DIR_RTL/LTR/WEAK/NEUTRAL`
|
||||
*/
|
||||
lv_bidi_dir_t lv_bidi_get_letter_dir(uint32_t letter)
|
||||
{
|
||||
if(lv_bidi_letter_is_rtl(letter)) return LV_BIDI_DIR_RTL;
|
||||
if(lv_bidi_letter_is_neutral(letter)) return LV_BIDI_DIR_NEUTRAL;
|
||||
if(lv_bidi_letter_is_weak(letter)) return LV_BIDI_DIR_WEAK;
|
||||
|
||||
return LV_BIDI_DIR_LTR;
|
||||
}
|
||||
/**
|
||||
* Tell whether a character is weak or not
|
||||
* @param letter an Unicode character
|
||||
* @return true/false
|
||||
*/
|
||||
bool lv_bidi_letter_is_weak(uint32_t letter)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
static const char weaks[] = "0123456789";
|
||||
|
||||
do {
|
||||
uint32_t x = lv_txt_encoded_next(weaks, &i);
|
||||
if(letter == x) {
|
||||
return true;
|
||||
}
|
||||
} while(weaks[i] != '\0');
|
||||
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Tell whether a character is RTL or not
|
||||
* @param letter an Unicode character
|
||||
* @return true/false
|
||||
*/
|
||||
bool lv_bidi_letter_is_rtl(uint32_t letter)
|
||||
{
|
||||
if(letter >= 0x5d0 && letter <= 0x5ea) return true;
|
||||
if(letter == 0x202E) return true; /*Unicode of LV_BIDI_RLO*/
|
||||
|
||||
/* Check for Persian and Arabic characters [https://en.wikipedia.org/wiki/Arabic_script_in_Unicode]*/
|
||||
if(letter >= 0x600 && letter <= 0x6FF) return true;
|
||||
if(letter >= 0xFB50 && letter <= 0xFDFF) return true;
|
||||
if(letter >= 0xFE70 && letter <= 0xFEFF) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether a character is neutral or not
|
||||
* @param letter an Unicode character
|
||||
* @return true/false
|
||||
*/
|
||||
bool lv_bidi_letter_is_neutral(uint32_t letter)
|
||||
{
|
||||
uint16_t i;
|
||||
static const char neutrals[] = " \t\n\r.,:;'\"`!?%/\\-=()[]{}<>@#&$|";
|
||||
for(i = 0; neutrals[i] != '\0'; i++) {
|
||||
if(letter == (uint32_t)neutrals[i]) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the logical position of a character in a line
|
||||
@@ -188,32 +130,32 @@ bool lv_bidi_letter_is_neutral(uint32_t letter)
|
||||
* Can be `NULL` is unused
|
||||
* @param len length of the line in character count
|
||||
* @param base_dir base direction of the text: `LV_BIDI_DIR_LTR` or `LV_BIDI_DIR_RTL`
|
||||
* @param vicual_pos the visual character position which logical position should be get
|
||||
* @param is_rtl tell the the char at `viasual_pos` is RTL or LTR context
|
||||
* @param visual_pos the visual character position which logical position should be get
|
||||
* @param is_rtl tell the the char at `visual_pos` is RTL or LTR context
|
||||
* @return the logical character position
|
||||
*/
|
||||
uint16_t lv_bidi_get_logical_pos(const char * str_in, char ** bidi_txt, uint32_t len, lv_bidi_dir_t base_dir,
|
||||
uint32_t visual_pos, bool * is_rtl)
|
||||
uint16_t _lv_bidi_get_logical_pos(const char * str_in, char ** bidi_txt, uint32_t len, lv_bidi_dir_t base_dir,
|
||||
uint32_t visual_pos, bool * is_rtl)
|
||||
{
|
||||
uint32_t pos_conv_len = get_txt_len(str_in, len);
|
||||
char * buf = lv_mem_buf_get(len + 1);
|
||||
char * buf = _lv_mem_buf_get(len + 1);
|
||||
if(buf == NULL) return (uint16_t) -1;
|
||||
|
||||
uint16_t * pos_conv_buf = lv_mem_buf_get(pos_conv_len * sizeof(uint16_t));
|
||||
uint16_t * pos_conv_buf = _lv_mem_buf_get(pos_conv_len * sizeof(uint16_t));
|
||||
if(pos_conv_buf == NULL) {
|
||||
lv_mem_buf_release(buf);
|
||||
_lv_mem_buf_release(buf);
|
||||
return (uint16_t) -1;
|
||||
}
|
||||
|
||||
if(bidi_txt) *bidi_txt = buf;
|
||||
|
||||
lv_bidi_process_paragraph(str_in, bidi_txt ? *bidi_txt : NULL, len, base_dir, pos_conv_buf, pos_conv_len);
|
||||
_lv_bidi_process_paragraph(str_in, bidi_txt ? *bidi_txt : NULL, len, base_dir, pos_conv_buf, pos_conv_len);
|
||||
|
||||
if(is_rtl) *is_rtl = IS_RTL_POS(pos_conv_buf[visual_pos]);
|
||||
|
||||
if(bidi_txt == NULL) lv_mem_buf_release(buf);
|
||||
if(bidi_txt == NULL) _lv_mem_buf_release(buf);
|
||||
uint16_t res = GET_POS(pos_conv_buf[visual_pos]);
|
||||
lv_mem_buf_release(pos_conv_buf);
|
||||
_lv_mem_buf_release(pos_conv_buf);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -229,35 +171,35 @@ uint16_t lv_bidi_get_logical_pos(const char * str_in, char ** bidi_txt, uint32_t
|
||||
* @param is_rtl tell the the char at `logical_pos` is RTL or LTR context
|
||||
* @return the visual character position
|
||||
*/
|
||||
uint16_t lv_bidi_get_visual_pos(const char * str_in, char ** bidi_txt, uint16_t len, lv_bidi_dir_t base_dir,
|
||||
uint32_t logical_pos, bool * is_rtl)
|
||||
uint16_t _lv_bidi_get_visual_pos(const char * str_in, char ** bidi_txt, uint16_t len, lv_bidi_dir_t base_dir,
|
||||
uint32_t logical_pos, bool * is_rtl)
|
||||
{
|
||||
uint32_t pos_conv_len = get_txt_len(str_in, len);
|
||||
char * buf = lv_mem_buf_get(len + 1);
|
||||
char * buf = _lv_mem_buf_get(len + 1);
|
||||
if(buf == NULL) return (uint16_t) -1;
|
||||
|
||||
uint16_t * pos_conv_buf = lv_mem_buf_get(pos_conv_len * sizeof(uint16_t));
|
||||
uint16_t * pos_conv_buf = _lv_mem_buf_get(pos_conv_len * sizeof(uint16_t));
|
||||
if(pos_conv_buf == NULL) {
|
||||
lv_mem_buf_release(buf);
|
||||
_lv_mem_buf_release(buf);
|
||||
return (uint16_t) -1;
|
||||
}
|
||||
|
||||
if(bidi_txt) *bidi_txt = buf;
|
||||
|
||||
lv_bidi_process_paragraph(str_in, bidi_txt ? *bidi_txt : NULL, len, base_dir, pos_conv_buf, pos_conv_len);
|
||||
_lv_bidi_process_paragraph(str_in, bidi_txt ? *bidi_txt : NULL, len, base_dir, pos_conv_buf, pos_conv_len);
|
||||
|
||||
for(uint16_t i = 0; i < pos_conv_len; i++) {
|
||||
if(GET_POS(pos_conv_buf[i]) == logical_pos) {
|
||||
|
||||
if(is_rtl) *is_rtl = IS_RTL_POS(pos_conv_buf[i]);
|
||||
lv_mem_buf_release(pos_conv_buf);
|
||||
_lv_mem_buf_release(pos_conv_buf);
|
||||
|
||||
if(bidi_txt == NULL) lv_mem_buf_release(buf);
|
||||
if(bidi_txt == NULL) _lv_mem_buf_release(buf);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
lv_mem_buf_release(pos_conv_buf);
|
||||
if(bidi_txt == NULL) lv_mem_buf_release(buf);
|
||||
_lv_mem_buf_release(pos_conv_buf);
|
||||
if(bidi_txt == NULL) _lv_mem_buf_release(buf);
|
||||
return (uint16_t) -1;
|
||||
}
|
||||
|
||||
@@ -265,14 +207,14 @@ uint16_t lv_bidi_get_visual_pos(const char * str_in, char ** bidi_txt, uint16_t
|
||||
* Bidi process a paragraph of text
|
||||
* @param str_in the string to process
|
||||
* @param str_out store the result here
|
||||
* @param len length of teh text
|
||||
* @param len length of the text
|
||||
* @param base_dir base dir of the text
|
||||
* @param pos_conv_out an `uint16_t` array to store the related logical position of the character.
|
||||
* Can be `NULL` is unused
|
||||
* @param pos_conv_len length of `pos_conv_out` in element count
|
||||
*/
|
||||
void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_bidi_dir_t base_dir,
|
||||
uint16_t * pos_conv_out, uint16_t pos_conv_len)
|
||||
void _lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_bidi_dir_t base_dir,
|
||||
uint16_t * pos_conv_out, uint16_t pos_conv_len)
|
||||
{
|
||||
uint32_t run_len = 0;
|
||||
lv_bidi_dir_t run_dir;
|
||||
@@ -282,7 +224,7 @@ void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len
|
||||
uint16_t pos_conv_rd = 0;
|
||||
uint16_t pos_conv_wr;
|
||||
|
||||
if(base_dir == LV_BIDI_DIR_AUTO) base_dir = lv_bidi_detect_base_dir(str_in);
|
||||
if(base_dir == LV_BIDI_DIR_AUTO) base_dir = _lv_bidi_detect_base_dir(str_in);
|
||||
if(base_dir == LV_BIDI_DIR_RTL) {
|
||||
wr = len;
|
||||
pos_conv_wr = pos_conv_len;
|
||||
@@ -301,7 +243,7 @@ void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len
|
||||
|
||||
/*Process neutral chars in the beginning*/
|
||||
while(rd < len) {
|
||||
uint32_t letter = lv_txt_encoded_next(str_in, &rd);
|
||||
uint32_t letter = _lv_txt_encoded_next(str_in, &rd);
|
||||
pos_conv_rd++;
|
||||
dir = lv_bidi_get_letter_dir(letter);
|
||||
if(dir == LV_BIDI_DIR_NEUTRAL) dir = bracket_process(str_in, rd, len, letter, base_dir);
|
||||
@@ -309,14 +251,14 @@ void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len
|
||||
}
|
||||
|
||||
if(rd && str_in[rd] != '\0') {
|
||||
lv_txt_encoded_prev(str_in, &rd);
|
||||
_lv_txt_encoded_prev(str_in, &rd);
|
||||
pos_conv_rd--;
|
||||
}
|
||||
|
||||
if(rd) {
|
||||
if(base_dir == LV_BIDI_DIR_LTR) {
|
||||
if(str_out) {
|
||||
lv_memcpy(&str_out[wr], str_in, rd);
|
||||
_lv_memcpy(&str_out[wr], str_in, rd);
|
||||
wr += rd;
|
||||
}
|
||||
if(pos_conv_out) {
|
||||
@@ -339,7 +281,7 @@ void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len
|
||||
|
||||
if(base_dir == LV_BIDI_DIR_LTR) {
|
||||
if(run_dir == LV_BIDI_DIR_LTR) {
|
||||
if(str_out) lv_memcpy(&str_out[wr], &str_in[rd], run_len);
|
||||
if(str_out) _lv_memcpy(&str_out[wr], &str_in[rd], run_len);
|
||||
if(pos_conv_out) fill_pos_conv(&pos_conv_out[pos_conv_wr], pos_conv_run_len, pos_conv_rd);
|
||||
}
|
||||
else rtl_reverse(str_out ? &str_out[wr] : NULL, &str_in[rd], run_len, pos_conv_out ? &pos_conv_out[pos_conv_wr] : NULL,
|
||||
@@ -351,7 +293,7 @@ void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len
|
||||
wr -= run_len;
|
||||
pos_conv_wr -= pos_conv_run_len;
|
||||
if(run_dir == LV_BIDI_DIR_LTR) {
|
||||
if(str_out) lv_memcpy(&str_out[wr], &str_in[rd], run_len);
|
||||
if(str_out) _lv_memcpy(&str_out[wr], &str_in[rd], run_len);
|
||||
if(pos_conv_out) fill_pos_conv(&pos_conv_out[pos_conv_wr], pos_conv_run_len, pos_conv_rd);
|
||||
}
|
||||
else rtl_reverse(str_out ? &str_out[wr] : NULL, &str_in[rd], run_len, pos_conv_out ? &pos_conv_out[pos_conv_wr] : NULL,
|
||||
@@ -363,27 +305,93 @@ void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Get the next paragraph from a text
|
||||
* @param txt the text to process
|
||||
* @return the length of the current paragraph in byte count
|
||||
*/
|
||||
uint32_t lv_bidi_get_next_paragraph(const char * txt)
|
||||
static uint32_t lv_bidi_get_next_paragraph(const char * txt)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
|
||||
lv_txt_encoded_next(txt, &i);
|
||||
_lv_txt_encoded_next(txt, &i);
|
||||
|
||||
while(txt[i] != '\0' && txt[i] != '\n' && txt[i] != '\r') {
|
||||
lv_txt_encoded_next(txt, &i);
|
||||
_lv_txt_encoded_next(txt, &i);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
/**
|
||||
* Get the direction of a character
|
||||
* @param letter an Unicode character
|
||||
* @return `LV_BIDI_DIR_RTL/LTR/WEAK/NEUTRAL`
|
||||
*/
|
||||
static lv_bidi_dir_t lv_bidi_get_letter_dir(uint32_t letter)
|
||||
{
|
||||
if(lv_bidi_letter_is_rtl(letter)) return LV_BIDI_DIR_RTL;
|
||||
if(lv_bidi_letter_is_neutral(letter)) return LV_BIDI_DIR_NEUTRAL;
|
||||
if(lv_bidi_letter_is_weak(letter)) return LV_BIDI_DIR_WEAK;
|
||||
|
||||
return LV_BIDI_DIR_LTR;
|
||||
}
|
||||
/**
|
||||
* Tell whether a character is weak or not
|
||||
* @param letter an Unicode character
|
||||
* @return true/false
|
||||
*/
|
||||
static bool lv_bidi_letter_is_weak(uint32_t letter)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
static const char weaks[] = "0123456789";
|
||||
|
||||
do {
|
||||
uint32_t x = _lv_txt_encoded_next(weaks, &i);
|
||||
if(letter == x) {
|
||||
return true;
|
||||
}
|
||||
} while(weaks[i] != '\0');
|
||||
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Tell whether a character is RTL or not
|
||||
* @param letter an Unicode character
|
||||
* @return true/false
|
||||
*/
|
||||
static bool lv_bidi_letter_is_rtl(uint32_t letter)
|
||||
{
|
||||
if(letter >= 0x5d0 && letter <= 0x5ea) return true;
|
||||
if(letter == 0x202E) return true; /*Unicode of LV_BIDI_RLO*/
|
||||
|
||||
/* Check for Persian and Arabic characters [https://en.wikipedia.org/wiki/Arabic_script_in_Unicode]*/
|
||||
if(letter >= 0x600 && letter <= 0x6FF) return true;
|
||||
if(letter >= 0xFB50 && letter <= 0xFDFF) return true;
|
||||
if(letter >= 0xFE70 && letter <= 0xFEFF) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether a character is neutral or not
|
||||
* @param letter an Unicode character
|
||||
* @return true/false
|
||||
*/
|
||||
static bool lv_bidi_letter_is_neutral(uint32_t letter)
|
||||
{
|
||||
uint16_t i;
|
||||
static const char neutrals[] = " \t\n\r.,:;'\"`!?%/\\-=()[]{}<>@#&$|";
|
||||
for(i = 0; neutrals[i] != '\0'; i++) {
|
||||
if(letter == (uint32_t)neutrals[i]) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static uint32_t get_txt_len(const char * txt, uint32_t max_len)
|
||||
{
|
||||
@@ -391,7 +399,7 @@ static uint32_t get_txt_len(const char * txt, uint32_t max_len)
|
||||
uint32_t i = 0;
|
||||
|
||||
while(i < max_len && txt[i] != '\0') {
|
||||
lv_txt_encoded_next(txt, &i);
|
||||
_lv_txt_encoded_next(txt, &i);
|
||||
len++;
|
||||
}
|
||||
|
||||
@@ -415,13 +423,13 @@ static lv_bidi_dir_t get_next_run(const char * txt, lv_bidi_dir_t base_dir, uint
|
||||
|
||||
uint16_t pos_conv_i = 0;
|
||||
|
||||
letter = lv_txt_encoded_next(txt, NULL);
|
||||
letter = _lv_txt_encoded_next(txt, NULL);
|
||||
lv_bidi_dir_t dir = lv_bidi_get_letter_dir(letter);
|
||||
if(dir == LV_BIDI_DIR_NEUTRAL) dir = bracket_process(txt, 0, max_len, letter, base_dir);
|
||||
|
||||
/*Find the first strong char. Skip the neutrals*/
|
||||
while(dir == LV_BIDI_DIR_NEUTRAL || dir == LV_BIDI_DIR_WEAK) {
|
||||
letter = lv_txt_encoded_next(txt, &i);
|
||||
letter = _lv_txt_encoded_next(txt, &i);
|
||||
pos_conv_i++;
|
||||
dir = lv_bidi_get_letter_dir(letter);
|
||||
if(dir == LV_BIDI_DIR_NEUTRAL) dir = bracket_process(txt, i, max_len, letter, base_dir);
|
||||
@@ -443,7 +451,7 @@ static lv_bidi_dir_t get_next_run(const char * txt, lv_bidi_dir_t base_dir, uint
|
||||
/*Find the next char which has different direction*/
|
||||
lv_bidi_dir_t next_dir = base_dir;
|
||||
while(i_prev < max_len && txt[i] != '\0' && txt[i] != '\n' && txt[i] != '\r') {
|
||||
letter = lv_txt_encoded_next(txt, &i);
|
||||
letter = _lv_txt_encoded_next(txt, &i);
|
||||
pos_conv_i++;
|
||||
next_dir = lv_bidi_get_letter_dir(letter);
|
||||
if(next_dir == LV_BIDI_DIR_NEUTRAL) next_dir = bracket_process(txt, i, max_len, letter, base_dir);
|
||||
@@ -498,7 +506,7 @@ static void rtl_reverse(char * dest, const char * src, uint32_t len, uint16_t *
|
||||
uint16_t pos_conv_wr = 0;
|
||||
|
||||
while(i) {
|
||||
uint32_t letter = lv_txt_encoded_prev(src, &i);
|
||||
uint32_t letter = _lv_txt_encoded_prev(src, &i);
|
||||
uint16_t pos_conv_letter = --pos_conv_i;
|
||||
|
||||
/*Keep weak letters (numbers) as LTR*/
|
||||
@@ -508,7 +516,7 @@ static void rtl_reverse(char * dest, const char * src, uint32_t len, uint16_t *
|
||||
uint16_t pos_conv_last_weak = pos_conv_i;
|
||||
uint16_t pos_conv_first_weak = pos_conv_i;
|
||||
while(i) {
|
||||
letter = lv_txt_encoded_prev(src, &i);
|
||||
letter = _lv_txt_encoded_prev(src, &i);
|
||||
pos_conv_letter = --pos_conv_i;
|
||||
|
||||
/*No need to call `char_change_to_pair` because there not such chars here*/
|
||||
@@ -516,7 +524,7 @@ static void rtl_reverse(char * dest, const char * src, uint32_t len, uint16_t *
|
||||
/*Finish on non-weak char */
|
||||
/*but treat number and currency related chars as weak*/
|
||||
if(lv_bidi_letter_is_weak(letter) == false && letter != '.' && letter != ',' && letter != '$' && letter != '%') {
|
||||
lv_txt_encoded_next(src, &i); /*Rewind one letter*/
|
||||
_lv_txt_encoded_next(src, &i); /*Rewind one letter*/
|
||||
pos_conv_i++;
|
||||
first_weak = i;
|
||||
pos_conv_first_weak = pos_conv_i;
|
||||
@@ -528,7 +536,7 @@ static void rtl_reverse(char * dest, const char * src, uint32_t len, uint16_t *
|
||||
pos_conv_first_weak = 0;
|
||||
}
|
||||
|
||||
if(dest) lv_memcpy(&dest[wr], &src[first_weak], last_weak - first_weak + 1);
|
||||
if(dest) _lv_memcpy(&dest[wr], &src[first_weak], last_weak - first_weak + 1);
|
||||
if(pos_conv_out) fill_pos_conv(&pos_conv_out[pos_conv_wr], pos_conv_last_weak - pos_conv_first_weak + 1,
|
||||
pos_conv_rd_base + pos_conv_first_weak);
|
||||
wr += last_weak - first_weak + 1;
|
||||
@@ -537,7 +545,7 @@ static void rtl_reverse(char * dest, const char * src, uint32_t len, uint16_t *
|
||||
|
||||
/*Simply store in reversed order*/
|
||||
else {
|
||||
uint32_t letter_size = lv_txt_encoded_size((const char *)&src[i]);
|
||||
uint32_t letter_size = _lv_txt_encoded_size((const char *)&src[i]);
|
||||
/*Swap arithmetical symbols*/
|
||||
if(letter_size == 1) {
|
||||
uint32_t new_letter = letter = char_change_to_pair(letter);
|
||||
@@ -548,7 +556,7 @@ static void rtl_reverse(char * dest, const char * src, uint32_t len, uint16_t *
|
||||
}
|
||||
/*Just store the letter*/
|
||||
else {
|
||||
if(dest) lv_memcpy(&dest[wr], &src[i], letter_size);
|
||||
if(dest) _lv_memcpy(&dest[wr], &src[i], letter_size);
|
||||
if(pos_conv_out) pos_conv_out[pos_conv_wr] = SET_RTL_POS(pos_conv_rd_base + pos_conv_i, true);
|
||||
wr += letter_size;
|
||||
pos_conv_wr++;
|
||||
@@ -585,7 +593,7 @@ static lv_bidi_dir_t bracket_process(const char * txt, uint32_t next_pos, uint32
|
||||
* If a char with base dir. direction is found then the brackets will have `base_dir` direction*/
|
||||
uint32_t txt_i = next_pos;
|
||||
while(txt_i < len) {
|
||||
uint32_t letter_next = lv_txt_encoded_next(txt, &txt_i);
|
||||
uint32_t letter_next = _lv_txt_encoded_next(txt, &txt_i);
|
||||
if(letter_next == bracket_right[i]) {
|
||||
/*Closing bracket found*/
|
||||
break;
|
||||
@@ -607,9 +615,9 @@ static lv_bidi_dir_t bracket_process(const char * txt, uint32_t next_pos, uint32
|
||||
|
||||
/*If there were no matching strong chars in the brackets then check the previous chars*/
|
||||
txt_i = next_pos;
|
||||
if(txt_i) lv_txt_encoded_prev(txt, &txt_i);
|
||||
if(txt_i) _lv_txt_encoded_prev(txt, &txt_i);
|
||||
while(txt_i > 0) {
|
||||
uint32_t letter_next = lv_txt_encoded_prev(txt, &txt_i);
|
||||
uint32_t letter_next = _lv_txt_encoded_prev(txt, &txt_i);
|
||||
lv_bidi_dir_t letter_dir = lv_bidi_get_letter_dir(letter_next);
|
||||
if(letter_dir == LV_BIDI_DIR_LTR || letter_dir == LV_BIDI_DIR_RTL) {
|
||||
bracket_dir = letter_dir;
|
||||
|
||||
@@ -54,42 +54,14 @@ typedef uint8_t lv_bidi_dir_t;
|
||||
* @param str_out store the result here. Has the be `strlen(str_in)` length
|
||||
* @param base_dir `LV_BIDI_DIR_LTR` or `LV_BIDI_DIR_RTL`
|
||||
*/
|
||||
void lv_bidi_process(const char * str_in, char * str_out, lv_bidi_dir_t base_dir);
|
||||
void _lv_bidi_process(const char * str_in, char * str_out, lv_bidi_dir_t base_dir);
|
||||
|
||||
/**
|
||||
* Auto-detect the direction of a text based on the first strong character
|
||||
* @param txt the text to process
|
||||
* @return `LV_BIDI_DIR_LTR` or `LV_BIDI_DIR_RTL`
|
||||
*/
|
||||
lv_bidi_dir_t lv_bidi_detect_base_dir(const char * txt);
|
||||
|
||||
/**
|
||||
* Get the direction of a character
|
||||
* @param letter an Unicode character
|
||||
* @return `LV_BIDI_DIR_RTL/LTR/WEAK/NEUTRAL`
|
||||
*/
|
||||
lv_bidi_dir_t lv_bidi_get_letter_dir(uint32_t letter);
|
||||
|
||||
/**
|
||||
* Tell whether a character is weak or not
|
||||
* @param letter an Unicode character
|
||||
* @return true/false
|
||||
*/
|
||||
bool lv_bidi_letter_is_weak(uint32_t letter);
|
||||
|
||||
/**
|
||||
* Tell whether a character is RTL or not
|
||||
* @param letter an Unicode character
|
||||
* @return true/false
|
||||
*/
|
||||
bool lv_bidi_letter_is_rtl(uint32_t letter);
|
||||
|
||||
/**
|
||||
* Tell whether a character is neutral or not
|
||||
* @param letter an Unicode character
|
||||
* @return true/false
|
||||
*/
|
||||
bool lv_bidi_letter_is_neutral(uint32_t letter);
|
||||
lv_bidi_dir_t _lv_bidi_detect_base_dir(const char * txt);
|
||||
|
||||
/**
|
||||
* Get the logical position of a character in a line
|
||||
@@ -99,12 +71,12 @@ bool lv_bidi_letter_is_neutral(uint32_t letter);
|
||||
* Can be `NULL` is unused
|
||||
* @param len length of the line in character count
|
||||
* @param base_dir base direction of the text: `LV_BIDI_DIR_LTR` or `LV_BIDI_DIR_RTL`
|
||||
* @param vicual_pos the visual character position which logical position should be get
|
||||
* @param is_rtl tell the the char at `viasual_pos` is RTL or LTR context
|
||||
* @param visual_pos the visual character position which logical position should be get
|
||||
* @param is_rtl tell the the char at `visual_pos` is RTL or LTR context
|
||||
* @return the logical character position
|
||||
*/
|
||||
uint16_t lv_bidi_get_logical_pos(const char * str_in, char ** bidi_txt, uint32_t len, lv_bidi_dir_t base_dir,
|
||||
uint32_t visual_pos, bool * is_rtl);
|
||||
uint16_t _lv_bidi_get_logical_pos(const char * str_in, char ** bidi_txt, uint32_t len, lv_bidi_dir_t base_dir,
|
||||
uint32_t visual_pos, bool * is_rtl);
|
||||
|
||||
/**
|
||||
* Get the visual position of a character in a line
|
||||
@@ -118,28 +90,21 @@ uint16_t lv_bidi_get_logical_pos(const char * str_in, char ** bidi_txt, uint32_t
|
||||
* @param is_rtl tell the the char at `logical_pos` is RTL or LTR context
|
||||
* @return the visual character position
|
||||
*/
|
||||
uint16_t lv_bidi_get_visual_pos(const char * str_in, char ** bidi_txt, uint16_t len, lv_bidi_dir_t base_dir,
|
||||
uint32_t logical_pos, bool * is_rtl);
|
||||
uint16_t _lv_bidi_get_visual_pos(const char * str_in, char ** bidi_txt, uint16_t len, lv_bidi_dir_t base_dir,
|
||||
uint32_t logical_pos, bool * is_rtl);
|
||||
|
||||
/**
|
||||
* Bidi process a paragraph of text
|
||||
* @param str_in the string to process
|
||||
* @param str_out store the result here
|
||||
* @param len length of teh text
|
||||
* @param len length of the text
|
||||
* @param base_dir base dir of the text
|
||||
* @param pos_conv_out an `uint16_t` array to store the related logical position of the character.
|
||||
* Can be `NULL` is unused
|
||||
* @param pos_conv_len length of `pos_conv_out` in element count
|
||||
*/
|
||||
void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_bidi_dir_t base_dir,
|
||||
uint16_t * pos_conv_out, uint16_t pos_conv_len);
|
||||
|
||||
/**
|
||||
* Get the next paragraph from a text
|
||||
* @param txt the text to process
|
||||
* @return the length of the current paragraph in byte count
|
||||
*/
|
||||
uint32_t lv_bidi_get_next_paragraph(const char * txt);
|
||||
void _lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_bidi_dir_t base_dir,
|
||||
uint16_t * pos_conv_out, uint16_t pos_conv_len);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
/**
|
||||
* @file lv_circ.c
|
||||
* Circle drawing algorithm (with Bresenham)
|
||||
* Only a 1/8 circle is calculated. Use CIRC_OCT1_X, CIRC_OCT1_Y macros to get
|
||||
* the other octets.
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_circ.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the circle drawing
|
||||
* @param c pointer to a point. The coordinates will be calculated here
|
||||
* @param tmp point to a variable. It will store temporary data
|
||||
* @param radius radius of the circle
|
||||
*/
|
||||
void lv_circ_init(lv_point_t * c, lv_coord_t * tmp, lv_coord_t radius)
|
||||
{
|
||||
c->x = radius;
|
||||
c->y = 0;
|
||||
*tmp = 1 - radius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the circle drawing is ready or not
|
||||
* @param c same as in circ_init
|
||||
* @return true if the circle is not ready yet
|
||||
*/
|
||||
bool lv_circ_cont(lv_point_t * c)
|
||||
{
|
||||
return c->y <= c->x ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next point from the circle
|
||||
* @param c same as in circ_init. The next point stored here.
|
||||
* @param tmp same as in circ_init.
|
||||
*/
|
||||
void lv_circ_next(lv_point_t * c, lv_coord_t * tmp)
|
||||
{
|
||||
c->y++;
|
||||
|
||||
if(*tmp <= 0) {
|
||||
(*tmp) += 2 * c->y + 1; /*Change in decision criterion for y -> y+1*/
|
||||
}
|
||||
else {
|
||||
c->x--;
|
||||
(*tmp) += 2 * (c->y - c->x) + 1; /*Change for y -> y+1, x -> x-1*/
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
@@ -1,77 +0,0 @@
|
||||
/**
|
||||
* @file lv_circ.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_CIRC_H
|
||||
#define LV_CIRC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include <stddef.h>
|
||||
#include "lv_area.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_CIRC_OCT1_X(p) (p.x)
|
||||
#define LV_CIRC_OCT1_Y(p) (p.y)
|
||||
#define LV_CIRC_OCT2_X(p) (p.y)
|
||||
#define LV_CIRC_OCT2_Y(p) (p.x)
|
||||
#define LV_CIRC_OCT3_X(p) (-p.y)
|
||||
#define LV_CIRC_OCT3_Y(p) (p.x)
|
||||
#define LV_CIRC_OCT4_X(p) (-p.x)
|
||||
#define LV_CIRC_OCT4_Y(p) (p.y)
|
||||
#define LV_CIRC_OCT5_X(p) (-p.x)
|
||||
#define LV_CIRC_OCT5_Y(p) (-p.y)
|
||||
#define LV_CIRC_OCT6_X(p) (-p.y)
|
||||
#define LV_CIRC_OCT6_Y(p) (-p.x)
|
||||
#define LV_CIRC_OCT7_X(p) (p.y)
|
||||
#define LV_CIRC_OCT7_Y(p) (-p.x)
|
||||
#define LV_CIRC_OCT8_X(p) (p.x)
|
||||
#define LV_CIRC_OCT8_Y(p) (-p.y)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the circle drawing
|
||||
* @param c pointer to a point. The coordinates will be calculated here
|
||||
* @param tmp point to a variable. It will store temporary data
|
||||
* @param radius radius of the circle
|
||||
*/
|
||||
void lv_circ_init(lv_point_t * c, lv_coord_t * tmp, lv_coord_t radius);
|
||||
|
||||
/**
|
||||
* Test the circle drawing is ready or not
|
||||
* @param c same as in circ_init
|
||||
* @return true if the circle is not ready yet
|
||||
*/
|
||||
bool lv_circ_cont(lv_point_t * c);
|
||||
|
||||
/**
|
||||
* Get the next point from the circle
|
||||
* @param c same as in circ_init. The next point stored here.
|
||||
* @param tmp same as in circ_init.
|
||||
*/
|
||||
void lv_circ_next(lv_point_t * c, lv_coord_t * tmp);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -39,33 +39,92 @@
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM void lv_color_fill(lv_color_t * buf, lv_color_t color, uint32_t px_num)
|
||||
{
|
||||
#if LV_COLOR_DEPTH == 16
|
||||
uintptr_t buf_int = (uintptr_t) buf;
|
||||
if(buf_int & 0x3) {
|
||||
*buf = color;
|
||||
buf++;
|
||||
px_num--;
|
||||
}
|
||||
|
||||
uint32_t c32 = color.full + (color.full << 16);
|
||||
uint32_t * buf32 = (uint32_t *)buf;
|
||||
|
||||
while(px_num > 16) {
|
||||
*buf = color; buf++;
|
||||
*buf = color; buf++;
|
||||
*buf = color; buf++;
|
||||
*buf = color; buf++;
|
||||
*buf32 = c32;
|
||||
buf32++;
|
||||
*buf32 = c32;
|
||||
buf32++;
|
||||
*buf32 = c32;
|
||||
buf32++;
|
||||
*buf32 = c32;
|
||||
buf32++;
|
||||
|
||||
*buf = color; buf++;
|
||||
*buf = color; buf++;
|
||||
*buf = color; buf++;
|
||||
*buf = color; buf++;
|
||||
|
||||
*buf = color; buf++;
|
||||
*buf = color; buf++;
|
||||
*buf = color; buf++;
|
||||
*buf = color; buf++;
|
||||
|
||||
*buf = color; buf++;
|
||||
*buf = color; buf++;
|
||||
*buf = color; buf++;
|
||||
*buf = color; buf++;
|
||||
*buf32 = c32;
|
||||
buf32++;
|
||||
*buf32 = c32;
|
||||
buf32++;
|
||||
*buf32 = c32;
|
||||
buf32++;
|
||||
*buf32 = c32;
|
||||
buf32++;
|
||||
|
||||
px_num -= 16;
|
||||
}
|
||||
while(px_num ) {
|
||||
*buf = color; buf++;
|
||||
|
||||
buf = (lv_color_t *)buf32;
|
||||
|
||||
while(px_num) {
|
||||
*buf = color;
|
||||
buf++;
|
||||
px_num --;
|
||||
}
|
||||
#else
|
||||
while(px_num > 16) {
|
||||
*buf = color;
|
||||
buf++;
|
||||
*buf = color;
|
||||
buf++;
|
||||
*buf = color;
|
||||
buf++;
|
||||
*buf = color;
|
||||
buf++;
|
||||
|
||||
*buf = color;
|
||||
buf++;
|
||||
*buf = color;
|
||||
buf++;
|
||||
*buf = color;
|
||||
buf++;
|
||||
*buf = color;
|
||||
buf++;
|
||||
|
||||
*buf = color;
|
||||
buf++;
|
||||
*buf = color;
|
||||
buf++;
|
||||
*buf = color;
|
||||
buf++;
|
||||
*buf = color;
|
||||
buf++;
|
||||
|
||||
*buf = color;
|
||||
buf++;
|
||||
*buf = color;
|
||||
buf++;
|
||||
*buf = color;
|
||||
buf++;
|
||||
*buf = color;
|
||||
buf++;
|
||||
|
||||
px_num -= 16;
|
||||
}
|
||||
while(px_num) {
|
||||
*buf = color;
|
||||
buf++;
|
||||
px_num --;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -72,8 +72,8 @@ enum {
|
||||
LV_OPA_COVER = 255,
|
||||
};
|
||||
|
||||
#define LV_OPA_MIN 5 /*Opacities below this will be transparent*/
|
||||
#define LV_OPA_MAX 250 /*Opacities above this will fully cover*/
|
||||
#define LV_OPA_MIN 2 /*Opacities below this will be transparent*/
|
||||
#define LV_OPA_MAX 253 /*Opacities above this will fully cover*/
|
||||
|
||||
#if LV_COLOR_DEPTH == 1
|
||||
#define LV_COLOR_SIZE 8
|
||||
@@ -88,6 +88,22 @@ enum {
|
||||
#endif
|
||||
|
||||
|
||||
/* Adjust color mix functions rounding.
|
||||
* GPUs might calculate color mix (blending) differently.
|
||||
* Should be in range of 0..254
|
||||
* 0: no adjustment, get the integer part of the result (round down)
|
||||
* 64: round up from x.75
|
||||
* 128: round up from half
|
||||
* 192: round up from x.25
|
||||
* 254: round up */
|
||||
#ifndef LV_COLOR_MIX_ROUND_OFS
|
||||
#if LV_COLOR_DEPTH == 32
|
||||
#define LV_COLOR_MIX_ROUND_OFS 0
|
||||
#else
|
||||
#define LV_COLOR_MIX_ROUND_OFS 128
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*---------------------------------------
|
||||
* Macros for all existing color depths
|
||||
* to set/get values of the color channels
|
||||
@@ -197,7 +213,7 @@ enum {
|
||||
**********************/
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
union {
|
||||
uint8_t blue : 1;
|
||||
uint8_t green : 1;
|
||||
uint8_t red : 1;
|
||||
@@ -374,7 +390,7 @@ static inline uint32_t lv_color_to32(lv_color_t color)
|
||||
{
|
||||
#if LV_COLOR_DEPTH == 1
|
||||
if(color.full == 0)
|
||||
return 0;
|
||||
return 0xFF000000;
|
||||
else
|
||||
return 0xFFFFFFFF;
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
@@ -426,6 +442,8 @@ static inline uint32_t lv_color_to32(lv_color_t color)
|
||||
}
|
||||
|
||||
|
||||
//! @cond Doxygen_Suppress
|
||||
|
||||
/**
|
||||
* Mix two colors with a given ratio.
|
||||
* @param c1 the first color to mix (usually the foreground)
|
||||
@@ -438,9 +456,12 @@ LV_ATTRIBUTE_FAST_MEM static inline lv_color_t lv_color_mix(lv_color_t c1, lv_co
|
||||
lv_color_t ret;
|
||||
#if LV_COLOR_DEPTH != 1
|
||||
/*LV_COLOR_DEPTH == 8, 16 or 32*/
|
||||
LV_COLOR_SET_R(ret, LV_MATH_UDIV255((uint16_t) LV_COLOR_GET_R(c1) * mix + LV_COLOR_GET_R(c2) * (255 - mix)));
|
||||
LV_COLOR_SET_G(ret, LV_MATH_UDIV255((uint16_t) LV_COLOR_GET_G(c1) * mix + LV_COLOR_GET_G(c2) * (255 - mix)));
|
||||
LV_COLOR_SET_B(ret, LV_MATH_UDIV255((uint16_t) LV_COLOR_GET_B(c1) * mix + LV_COLOR_GET_B(c2) * (255 - mix)));
|
||||
LV_COLOR_SET_R(ret, LV_MATH_UDIV255((uint16_t) LV_COLOR_GET_R(c1) * mix + LV_COLOR_GET_R(c2) *
|
||||
(255 - mix) + LV_COLOR_MIX_ROUND_OFS));
|
||||
LV_COLOR_SET_G(ret, LV_MATH_UDIV255((uint16_t) LV_COLOR_GET_G(c1) * mix + LV_COLOR_GET_G(c2) *
|
||||
(255 - mix) + LV_COLOR_MIX_ROUND_OFS));
|
||||
LV_COLOR_SET_B(ret, LV_MATH_UDIV255((uint16_t) LV_COLOR_GET_B(c1) * mix + LV_COLOR_GET_B(c2) *
|
||||
(255 - mix) + LV_COLOR_MIX_ROUND_OFS));
|
||||
LV_COLOR_SET_A(ret, 0xFF);
|
||||
#else
|
||||
/*LV_COLOR_DEPTH == 1*/
|
||||
@@ -457,6 +478,7 @@ LV_ATTRIBUTE_FAST_MEM static inline void lv_color_premult(lv_color_t c, uint8_t
|
||||
out[1] = (uint16_t) LV_COLOR_GET_G(c) * mix;
|
||||
out[2] = (uint16_t) LV_COLOR_GET_B(c) * mix;
|
||||
#else
|
||||
(void) mix;
|
||||
/*Pre-multiplication can't be used with 1 bpp*/
|
||||
out[0] = LV_COLOR_GET_R(c);
|
||||
out[1] = LV_COLOR_GET_G(c);
|
||||
@@ -465,6 +487,7 @@ LV_ATTRIBUTE_FAST_MEM static inline void lv_color_premult(lv_color_t c, uint8_t
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Mix two colors with a given ratio. It runs faster then `lv_color_mix` but requires some pre computation.
|
||||
* @param c1 The first color. Should be preprocessed with `lv_color_premult(c1)`
|
||||
@@ -479,9 +502,9 @@ LV_ATTRIBUTE_FAST_MEM static inline lv_color_t lv_color_mix_premult(uint16_t * p
|
||||
lv_color_t ret;
|
||||
#if LV_COLOR_DEPTH != 1
|
||||
/*LV_COLOR_DEPTH == 8, 16 or 32*/
|
||||
LV_COLOR_SET_R(ret, (uint16_t)((uint16_t) premult_c1[0] + LV_COLOR_GET_R(c2) * mix) >> 8);
|
||||
LV_COLOR_SET_G(ret, (uint16_t)((uint16_t) premult_c1[1] + LV_COLOR_GET_G(c2) * mix) >> 8);
|
||||
LV_COLOR_SET_B(ret, (uint16_t)((uint16_t) premult_c1[2] + LV_COLOR_GET_B(c2) * mix) >> 8);
|
||||
LV_COLOR_SET_R(ret, LV_MATH_UDIV255((uint16_t) premult_c1[0] + LV_COLOR_GET_R(c2) * mix + LV_COLOR_MIX_ROUND_OFS));
|
||||
LV_COLOR_SET_G(ret, LV_MATH_UDIV255((uint16_t) premult_c1[1] + LV_COLOR_GET_G(c2) * mix + LV_COLOR_MIX_ROUND_OFS));
|
||||
LV_COLOR_SET_B(ret, LV_MATH_UDIV255((uint16_t) premult_c1[2] + LV_COLOR_GET_B(c2) * mix + LV_COLOR_MIX_ROUND_OFS));
|
||||
LV_COLOR_SET_A(ret, 0xFF);
|
||||
#else
|
||||
/*LV_COLOR_DEPTH == 1*/
|
||||
@@ -506,8 +529,9 @@ LV_ATTRIBUTE_FAST_MEM static inline lv_color_t lv_color_mix_premult(uint16_t * p
|
||||
* @param res_color the result color
|
||||
* @param res_opa the result opacity
|
||||
*/
|
||||
LV_ATTRIBUTE_FAST_MEM static inline void lv_color_mix_with_alpha(lv_color_t bg_color, lv_opa_t bg_opa, lv_color_t fg_color, lv_opa_t fg_opa,
|
||||
lv_color_t * res_color, lv_opa_t * res_opa)
|
||||
LV_ATTRIBUTE_FAST_MEM static inline void lv_color_mix_with_alpha(lv_color_t bg_color, lv_opa_t bg_opa,
|
||||
lv_color_t fg_color, lv_opa_t fg_opa,
|
||||
lv_color_t * res_color, lv_opa_t * res_opa)
|
||||
{
|
||||
/* Pick the foreground if it's fully opaque or the Background is fully transparent*/
|
||||
if(fg_opa >= LV_OPA_MAX || bg_opa <= LV_OPA_MIN) {
|
||||
@@ -529,9 +553,9 @@ LV_ATTRIBUTE_FAST_MEM static inline void lv_color_mix_with_alpha(lv_color_t bg_c
|
||||
/*Save the parameters and the result. If they will be asked again don't compute again*/
|
||||
static lv_opa_t fg_opa_save = 0;
|
||||
static lv_opa_t bg_opa_save = 0;
|
||||
static lv_color_t fg_color_save = {{0}};
|
||||
static lv_color_t bg_color_save = {{0}};
|
||||
static lv_color_t res_color_saved = {{0}};
|
||||
static lv_color_t fg_color_save = {.full = 0};
|
||||
static lv_color_t bg_color_save = {.full = 0};
|
||||
static lv_color_t res_color_saved = {.full = 0};
|
||||
static lv_opa_t res_opa_saved = 0;
|
||||
|
||||
if(fg_opa != fg_opa_save || bg_opa != bg_opa_save || fg_color.full != fg_color_save.full ||
|
||||
@@ -557,6 +581,8 @@ LV_ATTRIBUTE_FAST_MEM static inline void lv_color_mix_with_alpha(lv_color_t bg_c
|
||||
}
|
||||
}
|
||||
|
||||
//! @endcond
|
||||
|
||||
/**
|
||||
* Get the brightness of a color
|
||||
* @param color a color
|
||||
@@ -570,19 +596,26 @@ static inline uint8_t lv_color_brightness(lv_color_t color)
|
||||
return (uint8_t)(bright >> 3);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* Fix of msvc 2019 compiler error C4576 inside C++ code */
|
||||
#define _LV_COLOR_MAKE_TYPE_HELPER lv_color_t
|
||||
#else
|
||||
#define _LV_COLOR_MAKE_TYPE_HELPER (lv_color_t)
|
||||
#endif
|
||||
|
||||
/* The most simple macro to create a color from R,G and B values */
|
||||
#if LV_COLOR_DEPTH == 1
|
||||
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){.full = (uint8_t)((b8 >> 7) | (g8 >> 7) | (r8 >> 7))})
|
||||
#define LV_COLOR_MAKE(r8, g8, b8) (_LV_COLOR_MAKE_TYPE_HELPER{.full = (uint8_t)((b8 >> 7) | (g8 >> 7) | (r8 >> 7))})
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{(uint8_t)((b8 >> 6) & 0x3U), (uint8_t)((g8 >> 5) & 0x7U), (uint8_t)((r8 >> 5) & 0x7U)}})
|
||||
#define LV_COLOR_MAKE(r8, g8, b8) (_LV_COLOR_MAKE_TYPE_HELPER{{(uint8_t)((b8 >> 6) & 0x3U), (uint8_t)((g8 >> 5) & 0x7U), (uint8_t)((r8 >> 5) & 0x7U)}})
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
#if LV_COLOR_16_SWAP == 0
|
||||
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{(uint16_t)((b8 >> 3) & 0x1FU), (uint16_t)((g8 >> 2) & 0x3FU), (uint16_t)((r8 >> 3) & 0x1FU)}})
|
||||
#define LV_COLOR_MAKE(r8, g8, b8) (_LV_COLOR_MAKE_TYPE_HELPER{{(uint16_t)((b8 >> 3) & 0x1FU), (uint16_t)((g8 >> 2) & 0x3FU), (uint16_t)((r8 >> 3) & 0x1FU)}})
|
||||
#else
|
||||
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{(uint16_t)((g8 >> 5) & 0x7U), (uint16_t)((r8 >> 3) & 0x1FU), (uint16_t)((b8 >> 3) & 0x1FU), (uint16_t)((g8 >> 2) & 0x7U)}})
|
||||
#define LV_COLOR_MAKE(r8, g8, b8) (_LV_COLOR_MAKE_TYPE_HELPER{{(uint16_t)((g8 >> 5) & 0x7U), (uint16_t)((r8 >> 3) & 0x1FU), (uint16_t)((b8 >> 3) & 0x1FU), (uint16_t)((g8 >> 2) & 0x7U)}})
|
||||
#endif
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8, g8, r8, 0xff}}) /*Fix 0xff alpha*/
|
||||
#define LV_COLOR_MAKE(r8, g8, b8) (_LV_COLOR_MAKE_TYPE_HELPER{{b8, g8, r8, 0xff}}) /*Fix 0xff alpha*/
|
||||
#endif
|
||||
|
||||
static inline lv_color_t lv_color_make(uint8_t r, uint8_t g, uint8_t b)
|
||||
@@ -601,8 +634,12 @@ static inline lv_color_t lv_color_hex3(uint32_t c)
|
||||
(uint8_t)((c & 0xF) | ((c & 0xF) << 4)));
|
||||
}
|
||||
|
||||
|
||||
//! @cond Doxygen_Suppress
|
||||
//!
|
||||
LV_ATTRIBUTE_FAST_MEM void lv_color_fill(lv_color_t * buf, lv_color_t color, uint32_t px_num);
|
||||
|
||||
//! @endcond
|
||||
lv_color_t lv_color_lighten(lv_color_t c, lv_opa_t lvl);
|
||||
|
||||
lv_color_t lv_color_darken(lv_color_t c, lv_opa_t lvl);
|
||||
|
||||
@@ -6,11 +6,13 @@
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj.h"
|
||||
#include "lv_debug.h"
|
||||
|
||||
#if LV_USE_DEBUG
|
||||
|
||||
#include "lv_mem.h"
|
||||
#include <string.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
@@ -28,7 +30,6 @@
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_find);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@@ -54,68 +55,6 @@ bool lv_debug_check_mem_integrity(void)
|
||||
return lv_mem_test() == LV_RES_OK ? true : false;
|
||||
}
|
||||
|
||||
bool lv_debug_check_obj_type(const lv_obj_t * obj, const char * obj_type)
|
||||
{
|
||||
if(obj_type[0] == '\0') return true;
|
||||
|
||||
lv_obj_type_t types;
|
||||
lv_obj_get_type((lv_obj_t *)obj, &types);
|
||||
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM; i++) {
|
||||
if(types.type[i] == NULL) break;
|
||||
if(strcmp(types.type[i], obj_type) == 0) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool lv_debug_check_obj_valid(const lv_obj_t * obj)
|
||||
{
|
||||
lv_disp_t * disp = lv_disp_get_next(NULL);
|
||||
while(disp) {
|
||||
lv_obj_t * scr;
|
||||
LV_LL_READ(disp->scr_ll, scr) {
|
||||
|
||||
if(scr == obj) return true;
|
||||
bool found = obj_valid_child(scr, obj);
|
||||
if(found) return true;
|
||||
}
|
||||
|
||||
disp = lv_disp_get_next(disp);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool lv_debug_check_style(const lv_style_t * style)
|
||||
{
|
||||
if(style == NULL) return true; /*NULL style is still valid*/
|
||||
|
||||
#if LV_USE_ASSERT_STYLE
|
||||
if(style->sentinel != LV_DEBUG_STYLE_SENTINEL_VALUE) {
|
||||
LV_LOG_WARN("Invalid style (local variable or not initialized?)");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lv_debug_check_style_list(const lv_style_list_t * list)
|
||||
{
|
||||
if(list == NULL) return true; /*NULL list is still valid*/
|
||||
|
||||
#if LV_USE_ASSERT_STYLE
|
||||
if(list->sentinel != LV_DEBUG_STYLE_LIST_SENTINEL_VALUE) {
|
||||
LV_LOG_WARN("Invalid style (local variable or not initialized?)");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lv_debug_check_str(const void * str)
|
||||
{
|
||||
const uint8_t * s = (const uint8_t *)str;
|
||||
@@ -160,7 +99,7 @@ void lv_debug_log_error(const char * msg, uint64_t value)
|
||||
char * bufp = buf;
|
||||
|
||||
/*Add the function name*/
|
||||
lv_memcpy(bufp, msg, msg_len);
|
||||
_lv_memcpy(bufp, msg, msg_len);
|
||||
bufp += msg_len;
|
||||
|
||||
/*Add value in hey*/
|
||||
@@ -196,20 +135,6 @@ void lv_debug_log_error(const char * msg, uint64_t value)
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_find)
|
||||
{
|
||||
/*Check all children of `parent`*/
|
||||
lv_obj_t * child;
|
||||
LV_LL_READ(parent->child_ll, child) {
|
||||
if(child == obj_to_find) return true;
|
||||
|
||||
/*Check the children*/
|
||||
bool found = obj_valid_child(child, obj_to_find);
|
||||
if(found) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DEBUG*/
|
||||
|
||||
@@ -13,9 +13,10 @@ extern "C" {
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj.h"
|
||||
#include "../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_DEBUG
|
||||
#include <stdbool.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -32,14 +33,6 @@ bool lv_debug_check_null(const void * p);
|
||||
|
||||
bool lv_debug_check_mem_integrity(void);
|
||||
|
||||
bool lv_debug_check_obj_type(const lv_obj_t * obj, const char * obj_type);
|
||||
|
||||
bool lv_debug_check_obj_valid(const lv_obj_t * obj);
|
||||
|
||||
bool lv_debug_check_style(const lv_style_t * style);
|
||||
|
||||
bool lv_debug_check_style_list(const lv_style_list_t * list);
|
||||
|
||||
bool lv_debug_check_str(const void * str);
|
||||
|
||||
void lv_debug_log_error(const char * msg, uint64_t value);
|
||||
@@ -77,20 +70,6 @@ void lv_debug_log_error(const char * msg, uint64_t value);
|
||||
lv_debug_check_str(str))
|
||||
#endif
|
||||
|
||||
#ifndef LV_DEBUG_IS_OBJ
|
||||
#define LV_DEBUG_IS_OBJ(obj_p, obj_type) (lv_debug_check_null(obj_p) && \
|
||||
lv_debug_check_obj_valid(obj_p) && \
|
||||
lv_debug_check_obj_type(obj_p, obj_type))
|
||||
#endif
|
||||
|
||||
#ifndef LV_DEBUG_IS_STYLE
|
||||
#define LV_DEBUG_IS_STYLE(style_p) (lv_debug_check_style(style_p))
|
||||
#endif
|
||||
|
||||
#ifndef LV_DEBUG_IS_STYLE_LIST
|
||||
#define LV_DEBUG_IS_STYLE_LIST(list_p) (lv_debug_check_style_list(list_p))
|
||||
#endif
|
||||
|
||||
/*-----------------
|
||||
* ASSERTS
|
||||
*-----------------*/
|
||||
@@ -133,30 +112,6 @@ void lv_debug_log_error(const char * msg, uint64_t value);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if LV_USE_ASSERT_OBJ
|
||||
# ifndef LV_ASSERT_OBJ
|
||||
# define LV_ASSERT_OBJ(obj_p, obj_type) LV_DEBUG_ASSERT(LV_DEBUG_IS_OBJ(obj_p, obj_type), "Invalid object", obj_p);
|
||||
# endif
|
||||
#else /* LV_USE_ASSERT_OBJ == 0 */
|
||||
# if LV_USE_ASSERT_NULL /*Use at least LV_ASSERT_NULL if enabled*/
|
||||
# define LV_ASSERT_OBJ(obj_p, obj_type) LV_ASSERT_NULL(obj_p)
|
||||
# else
|
||||
# define LV_ASSERT_OBJ(obj_p, obj_type) true
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#if LV_USE_ASSERT_STYLE
|
||||
# ifndef LV_ASSERT_STYLE
|
||||
# define LV_ASSERT_STYLE(style_p) LV_DEBUG_ASSERT(LV_DEBUG_IS_STYLE(style_p), "Invalid style", style_p);
|
||||
# endif
|
||||
# ifndef LV_ASSERT_STYLE_LIST
|
||||
# define LV_ASSERT_STYLE_LIST(list_p) LV_DEBUG_ASSERT(LV_DEBUG_IS_STYLE_LIST(list_p), "Invalid style list", list_p);
|
||||
# endif
|
||||
#else
|
||||
# define LV_ASSERT_STYLE(style_p) true
|
||||
# define LV_ASSERT_STYLE_LIST(list_p) true
|
||||
#endif
|
||||
|
||||
#else /* LV_USE_DEBUG == 0 */
|
||||
|
||||
@@ -167,8 +122,6 @@ void lv_debug_log_error(const char * msg, uint64_t value);
|
||||
#define LV_ASSERT_MEM_INTEGRITY() true
|
||||
#define LV_ASSERT_STR(p) true
|
||||
#define LV_ASSERT_OBJ(obj, obj_type) true
|
||||
#define LV_ASSERT_STYLE(p) true
|
||||
#define LV_ASSERT_STYLE_LIST(p) true
|
||||
|
||||
#endif /* LV_USE_DEBUG */
|
||||
/*clang-format on*/
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "lv_fs.h"
|
||||
#if LV_USE_FILESYSTEM
|
||||
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "../lv_misc/lv_debug.h"
|
||||
#include "lv_ll.h"
|
||||
#include <string.h>
|
||||
#include "lv_gc.h"
|
||||
@@ -54,13 +54,13 @@ static const char * lv_fs_get_real_path(const char * path);
|
||||
/**
|
||||
* Initialize the File system interface
|
||||
*/
|
||||
void lv_fs_init(void)
|
||||
void _lv_fs_init(void)
|
||||
{
|
||||
lv_ll_init(&LV_GC_ROOT(_lv_drv_ll), sizeof(lv_fs_drv_t));
|
||||
_lv_ll_init(&LV_GC_ROOT(_lv_drv_ll), sizeof(lv_fs_drv_t));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a drive is rady or not. If the `ready` function was not initialized `true` will be
|
||||
* Test if a drive is ready or not. If the `ready` function was not initialized `true` will be
|
||||
* returned.
|
||||
* @param letter letter of the drive
|
||||
* @return true: drive is ready; false: drive is not ready
|
||||
@@ -475,7 +475,7 @@ lv_fs_res_t lv_fs_free_space(char letter, uint32_t * total_p, uint32_t * free_p)
|
||||
*/
|
||||
void lv_fs_drv_init(lv_fs_drv_t * drv)
|
||||
{
|
||||
lv_memset_00(drv, sizeof(lv_fs_drv_t));
|
||||
_lv_memset_00(drv, sizeof(lv_fs_drv_t));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -487,11 +487,11 @@ void lv_fs_drv_register(lv_fs_drv_t * drv_p)
|
||||
{
|
||||
/*Save the new driver*/
|
||||
lv_fs_drv_t * new_drv;
|
||||
new_drv = lv_ll_ins_head(&LV_GC_ROOT(_lv_drv_ll));
|
||||
new_drv = _lv_ll_ins_head(&LV_GC_ROOT(_lv_drv_ll));
|
||||
LV_ASSERT_MEM(new_drv);
|
||||
if(new_drv == NULL) return;
|
||||
|
||||
lv_memcpy(new_drv, drv_p, sizeof(lv_fs_drv_t));
|
||||
_lv_memcpy(new_drv, drv_p, sizeof(lv_fs_drv_t));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -503,7 +503,7 @@ lv_fs_drv_t * lv_fs_get_drv(char letter)
|
||||
{
|
||||
lv_fs_drv_t * drv;
|
||||
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_drv_ll), drv) {
|
||||
_LV_LL_READ(LV_GC_ROOT(_lv_drv_ll), drv) {
|
||||
if(drv->letter == letter) {
|
||||
return drv;
|
||||
}
|
||||
@@ -521,7 +521,7 @@ char * lv_fs_get_letters(char * buf)
|
||||
lv_fs_drv_t * drv;
|
||||
uint8_t i = 0;
|
||||
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_drv_ll), drv) {
|
||||
_LV_LL_READ(LV_GC_ROOT(_lv_drv_ll), drv) {
|
||||
buf[i] = drv->letter;
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ typedef struct {
|
||||
/**
|
||||
* Initialize the File system interface
|
||||
*/
|
||||
void lv_fs_init(void);
|
||||
void _lv_fs_init(void);
|
||||
|
||||
/**
|
||||
* Initialize a file system driver with default values.
|
||||
@@ -129,7 +129,7 @@ void lv_fs_drv_register(lv_fs_drv_t * drv_p);
|
||||
lv_fs_drv_t * lv_fs_get_drv(char letter);
|
||||
|
||||
/**
|
||||
* Test if a drive is rady or not. If the `ready` function was not initialized `true` will be
|
||||
* Test if a drive is ready or not. If the `ready` function was not initialized `true` will be
|
||||
* returned.
|
||||
* @param letter letter of the drive
|
||||
* @return true: drive is ready; false: drive is not ready
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user