Compare commits
931 Commits
pango2
...
async-colo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35b0974000 | ||
|
|
4c18b1f345 | ||
|
|
48aa551a72 | ||
|
|
c20749e2d8 | ||
|
|
3e8a5bbb92 | ||
|
|
056022a54b | ||
|
|
1765bdc590 | ||
|
|
bcd9130548 | ||
|
|
a95cfb1c45 | ||
|
|
799fb41937 | ||
|
|
e6f4c596fa | ||
|
|
3d7fb26588 | ||
|
|
93f9b2d519 | ||
|
|
6f3613a06f | ||
|
|
3723778f42 | ||
|
|
3fc3f8d2ff | ||
|
|
2868f1b509 | ||
|
|
f44570e71a | ||
|
|
15d39dddc5 | ||
|
|
1028449bcc | ||
|
|
01cca279f9 | ||
|
|
a7cae4bffa | ||
|
|
3e2e29a1dc | ||
|
|
de069e15c2 | ||
|
|
f8edefd7c0 | ||
|
|
24a15b51fe | ||
|
|
1f7aba345d | ||
|
|
230212c59c | ||
|
|
86f7c19b91 | ||
|
|
e5cea4e39d | ||
|
|
22aca8952f | ||
|
|
c0e437d163 | ||
|
|
ffe97a453f | ||
|
|
c09ba28b06 | ||
|
|
81de43eba5 | ||
|
|
788be8b945 | ||
|
|
0370979225 | ||
|
|
943014074c | ||
|
|
c0e8523a01 | ||
|
|
8374ebe4c4 | ||
|
|
611d14108d | ||
|
|
25cf702345 | ||
|
|
1d9c61cada | ||
|
|
71adb26a0d | ||
|
|
e27fa33690 | ||
|
|
f7dfead861 | ||
|
|
aac04a0995 | ||
|
|
8af191e52d | ||
|
|
06382ff836 | ||
|
|
cd469788c3 | ||
|
|
44b5076cf2 | ||
|
|
e5be9e1035 | ||
|
|
b831d01f0d | ||
|
|
278bcf2680 | ||
|
|
c19d0dc9ea | ||
|
|
edd5ed169e | ||
|
|
8ec9c3fdc6 | ||
|
|
e95022040f | ||
|
|
3a2ce620e2 | ||
|
|
df49bf9eec | ||
|
|
53327f3aea | ||
|
|
c0c3d75062 | ||
|
|
d0d0409f9d | ||
|
|
3a7d094542 | ||
|
|
280adcbb8c | ||
|
|
83431a999c | ||
|
|
eeeee99aa8 | ||
|
|
0f503e0ba2 | ||
|
|
3e4ae62b44 | ||
|
|
ec4f814bd4 | ||
|
|
0141ba4e00 | ||
|
|
52ef16c21b | ||
|
|
6ca7104015 | ||
|
|
07d6166ab8 | ||
|
|
dc651c3dc3 | ||
|
|
f520801626 | ||
|
|
4e3fbd0b0f | ||
|
|
8a24fdea38 | ||
|
|
b26222b6ba | ||
|
|
c8d291ab86 | ||
|
|
0a87438432 | ||
|
|
ddf1cd6678 | ||
|
|
9c6d5e2ca5 | ||
|
|
1f2561b08e | ||
|
|
d5b31a30fd | ||
|
|
39c678988d | ||
|
|
9052c191cb | ||
|
|
766f442636 | ||
|
|
27a3d2d09e | ||
|
|
3a3482e41e | ||
|
|
44c37fa34a | ||
|
|
5c41dbfaa5 | ||
|
|
c9d2ff7a0f | ||
|
|
174af596c5 | ||
|
|
de2624faa7 | ||
|
|
cda784a5f4 | ||
|
|
cc33dbef03 | ||
|
|
ce36611c4e | ||
|
|
038cb31d27 | ||
|
|
3b53a6b0a9 | ||
|
|
619ff2338e | ||
|
|
2bcd6949df | ||
|
|
abd78ce5f5 | ||
|
|
7899fc03c4 | ||
|
|
9984f00781 | ||
|
|
a0d3bdc911 | ||
|
|
b96317b872 | ||
|
|
6c84958b9f | ||
|
|
f2559b1dbb | ||
|
|
ed2ade4801 | ||
|
|
4549172825 | ||
|
|
b877804eb6 | ||
|
|
5310abbcf7 | ||
|
|
490d4b0b9e | ||
|
|
375432f0b6 | ||
|
|
c00a23ebbc | ||
|
|
4cd2e2a11f | ||
|
|
ae7bf4dcf7 | ||
|
|
9ed1505073 | ||
|
|
e040d3663e | ||
|
|
6af69a7b7d | ||
|
|
a116e0dd26 | ||
|
|
3e2b962a36 | ||
|
|
abb60ec579 | ||
|
|
b738d4a6ac | ||
|
|
0149bd49ca | ||
|
|
e05157437f | ||
|
|
e045e798a2 | ||
|
|
7908a72fa9 | ||
|
|
593bf2bc6d | ||
|
|
cf701d5db4 | ||
|
|
bf8d4c5418 | ||
|
|
912145c81b | ||
|
|
913127b553 | ||
|
|
62f85e2f49 | ||
|
|
4b1212eb4a | ||
|
|
94a096ec4c | ||
|
|
404ee55ec4 | ||
|
|
5fbd52da49 | ||
|
|
7bf094c117 | ||
|
|
4bb79decf3 | ||
|
|
60fb93e063 | ||
|
|
1894a8960e | ||
|
|
4ba5c90bc9 | ||
|
|
1d16bd7d30 | ||
|
|
17819ad4f6 | ||
|
|
ac1ea6faca | ||
|
|
8a3f1a1fa1 | ||
|
|
46c7c0c4e6 | ||
|
|
dd60a9abd6 | ||
|
|
50835ffbf6 | ||
|
|
637713fe72 | ||
|
|
7e71c868ab | ||
|
|
aaf5c43e78 | ||
|
|
5fb6f0e410 | ||
|
|
cd031de680 | ||
|
|
eeda25ab04 | ||
|
|
acaf04a24e | ||
|
|
bcabe77799 | ||
|
|
64cf31f348 | ||
|
|
e037155a94 | ||
|
|
55cbb8a8d6 | ||
|
|
db599f2ae6 | ||
|
|
741567868e | ||
|
|
1e5e0480fd | ||
|
|
917aa7928d | ||
|
|
cd4dbd67a2 | ||
|
|
5a6eab05e9 | ||
|
|
55ccaf9df9 | ||
|
|
af0e056eec | ||
|
|
77d1f0d982 | ||
|
|
d4d7d5eafd | ||
|
|
f658027c51 | ||
|
|
7be993b728 | ||
|
|
e1d78821f6 | ||
|
|
94ac1af293 | ||
|
|
b4db48935d | ||
|
|
f5063c1435 | ||
|
|
8092a6858e | ||
|
|
0fbaeaabd0 | ||
|
|
995f00d23f | ||
|
|
100605ef0c | ||
|
|
1246cd5e73 | ||
|
|
f30e59fed9 | ||
|
|
5e8b294faf | ||
|
|
c84c469b78 | ||
|
|
1a5a65acd0 | ||
|
|
6f5d18a9f5 | ||
|
|
004f22a51c | ||
|
|
d775caff7f | ||
|
|
baf3a3eecd | ||
|
|
ca2e14788d | ||
|
|
c57d8fc6be | ||
|
|
294e5bb79f | ||
|
|
bde19f9b2a | ||
|
|
1d2071b892 | ||
|
|
b46eb5c20a | ||
|
|
3d605615ce | ||
|
|
c502d7fca6 | ||
|
|
9f8abc5d74 | ||
|
|
c8cbb3fbba | ||
|
|
fa3c8ed5f9 | ||
|
|
8ac5f1983e | ||
|
|
eccc02d084 | ||
|
|
0c94db7147 | ||
|
|
ed87473bf9 | ||
|
|
812a879ec2 | ||
|
|
5627542d7c | ||
|
|
f42fe500c9 | ||
|
|
ac3177ce95 | ||
|
|
ccaaff406f | ||
|
|
b1ec43ae33 | ||
|
|
ee8c2a235f | ||
|
|
299fbfd722 | ||
|
|
5f54ecdf2c | ||
|
|
e09138ce45 | ||
|
|
a71893f88b | ||
|
|
01324ffaff | ||
|
|
c354465ed8 | ||
|
|
50ab2386ec | ||
|
|
bf9f362597 | ||
|
|
d03ee57cc5 | ||
|
|
6f24bd9ff4 | ||
|
|
616e0a0d32 | ||
|
|
ee76105119 | ||
|
|
381f863a18 | ||
|
|
57c63d9ce7 | ||
|
|
0522dade9f | ||
|
|
484cff2182 | ||
|
|
dd3c371c08 | ||
|
|
3145bce6a1 | ||
|
|
73f991a7fd | ||
|
|
0205caa371 | ||
|
|
c2c46a7036 | ||
|
|
2b00b64e8c | ||
|
|
4e2522a080 | ||
|
|
473065dfeb | ||
|
|
60dafebd91 | ||
|
|
35370752d5 | ||
|
|
808d00906c | ||
|
|
da5d5bd71f | ||
|
|
0c99e69423 | ||
|
|
410813eb6b | ||
|
|
6cc44eb0fe | ||
|
|
11ee930b9d | ||
|
|
69e4c9b01e | ||
|
|
c32fed9238 | ||
|
|
4941ef659f | ||
|
|
6efb18330f | ||
|
|
5e256590db | ||
|
|
79303d7cd3 | ||
|
|
681a818af2 | ||
|
|
933b1eb4df | ||
|
|
c419b57754 | ||
|
|
05323869d7 | ||
|
|
2520148ebb | ||
|
|
a06a4ad59a | ||
|
|
141aac1a60 | ||
|
|
8a1578ede8 | ||
|
|
8ba7840528 | ||
|
|
3168a3e086 | ||
|
|
3cf9149129 | ||
|
|
7c8a098852 | ||
|
|
ecbdb3104a | ||
|
|
c8a332b3af | ||
|
|
b5f7d57124 | ||
|
|
0db5c7f421 | ||
|
|
ed83272f35 | ||
|
|
20b49e7c34 | ||
|
|
6a6ef0f437 | ||
|
|
32ef462f1d | ||
|
|
b895360f49 | ||
|
|
c2c094e8a1 | ||
|
|
d4d0192405 | ||
|
|
15ea36e7fd | ||
|
|
692279586a | ||
|
|
9eec475dcc | ||
|
|
661130d429 | ||
|
|
68b73ebf91 | ||
|
|
08c0020ac3 | ||
|
|
ac87c72797 | ||
|
|
5be8710774 | ||
|
|
5fa027ab8a | ||
|
|
dbe04adb1a | ||
|
|
6815f3af6d | ||
|
|
f8357512d0 | ||
|
|
8bfc19e7f7 | ||
|
|
d6f7449636 | ||
|
|
f4286e8f1a | ||
|
|
14e6fd1f12 | ||
|
|
2e57621fc5 | ||
|
|
4a8ae3a20c | ||
|
|
61393fdcce | ||
|
|
6ed6cebcf4 | ||
|
|
2f764f6c18 | ||
|
|
a646e50019 | ||
|
|
e967dfed2d | ||
|
|
2dc33a9de1 | ||
|
|
7c5e1c6195 | ||
|
|
8607312fef | ||
|
|
abac891bd2 | ||
|
|
2e25a13fc0 | ||
|
|
7a2c4e8a38 | ||
|
|
90e0ace325 | ||
|
|
9a2a5d9c8b | ||
|
|
d4dd0dcd79 | ||
|
|
d454586927 | ||
|
|
1917b6a0a3 | ||
|
|
a924b820c2 | ||
|
|
9e82d2b843 | ||
|
|
ab7a04d89f | ||
|
|
a377f95aac | ||
|
|
4356e0c3ce | ||
|
|
5d5de9f759 | ||
|
|
e1f69ea278 | ||
|
|
6a76fe41c6 | ||
|
|
aae82d7992 | ||
|
|
ca576e877f | ||
|
|
bc23038848 | ||
|
|
43e8730acd | ||
|
|
c43def5fce | ||
|
|
e68b365fa1 | ||
|
|
3867f9b8ea | ||
|
|
0b20c57867 | ||
|
|
7e9ca5b41d | ||
|
|
a527a4d82e | ||
|
|
adfc29968a | ||
|
|
e17e94d2da | ||
|
|
9af3bb8dc1 | ||
|
|
998dd11cbd | ||
|
|
9cb8d21cb5 | ||
|
|
4fc4298920 | ||
|
|
230188fb30 | ||
|
|
a96c75ff02 | ||
|
|
1b4ed00509 | ||
|
|
a54284b629 | ||
|
|
ee9e9bb3e1 | ||
|
|
cae9689281 | ||
|
|
1f6e2cf291 | ||
|
|
69a76054e8 | ||
|
|
31fea11255 | ||
|
|
5dd7e24806 | ||
|
|
848dc78112 | ||
|
|
e9d7cd3a48 | ||
|
|
b3a3a6ceb1 | ||
|
|
148c133674 | ||
|
|
d2c9cbba4f | ||
|
|
8b33900e1d | ||
|
|
0c3572312a | ||
|
|
7e683ed89b | ||
|
|
7fb892460a | ||
|
|
d517804acd | ||
|
|
ce761122b2 | ||
|
|
76a5354ad7 | ||
|
|
006b473c0c | ||
|
|
5e1af6d7d5 | ||
|
|
ec0cd4a994 | ||
|
|
86864d7bc0 | ||
|
|
485ffcde38 | ||
|
|
0304eaec94 | ||
|
|
a7814a0963 | ||
|
|
160a83023a | ||
|
|
911abe2d2c | ||
|
|
0c02573c47 | ||
|
|
4257e1ce4f | ||
|
|
39bc13c8a7 | ||
|
|
dd7cd6ffdd | ||
|
|
349cda3d36 | ||
|
|
48cc56081d | ||
|
|
aa9a7a931d | ||
|
|
3aee45de28 | ||
|
|
5f469d8903 | ||
|
|
2ce2e90205 | ||
|
|
8b76cc841d | ||
|
|
75b1d75751 | ||
|
|
2d19a1f1ec | ||
|
|
e57d005076 | ||
|
|
31d483dfbc | ||
|
|
fc2cb9d063 | ||
|
|
91cc03a81a | ||
|
|
67049c3261 | ||
|
|
c98cea3dbb | ||
|
|
0a67ac6d47 | ||
|
|
f8c0d86d6c | ||
|
|
872e04f94e | ||
|
|
d5c60438d1 | ||
|
|
60788913da | ||
|
|
f01118f2fc | ||
|
|
9db812ea7f | ||
|
|
d538e78d8a | ||
|
|
ba0499a803 | ||
|
|
1318fdc52c | ||
|
|
d3c50fad6c | ||
|
|
e2219858ae | ||
|
|
85043a2d1b | ||
|
|
cac813bbc4 | ||
|
|
94a4c2cb40 | ||
|
|
11829fe7d0 | ||
|
|
455eefa854 | ||
|
|
0f4f90d722 | ||
|
|
cefb0a3eb8 | ||
|
|
bc661a8ed5 | ||
|
|
9ff549799d | ||
|
|
e499a09759 | ||
|
|
fb280e47d6 | ||
|
|
4aabc45685 | ||
|
|
a8af7caae1 | ||
|
|
7d2c296357 | ||
|
|
c24a69549d | ||
|
|
f141da6b55 | ||
|
|
3688ece655 | ||
|
|
61a51dea7b | ||
|
|
bccb4f87be | ||
|
|
52b6dbf2b4 | ||
|
|
f33f55bcbb | ||
|
|
f4d3f45c16 | ||
|
|
1e65d6640f | ||
|
|
8a4fd30797 | ||
|
|
9818ec4ad9 | ||
|
|
4d08eb264d | ||
|
|
bc159207bd | ||
|
|
1f166ae071 | ||
|
|
ce4c2154f4 | ||
|
|
71fedee85d | ||
|
|
90c2b548e5 | ||
|
|
1d48f96fc5 | ||
|
|
10255eee72 | ||
|
|
5b2568e9e4 | ||
|
|
be6413b0e7 | ||
|
|
15d1c86b2c | ||
|
|
dd47e3bcab | ||
|
|
872534e763 | ||
|
|
d351cbbcea | ||
|
|
6c95547c3f | ||
|
|
c7a7e550dc | ||
|
|
ee1a634c25 | ||
|
|
55ab99cb98 | ||
|
|
f50b0a0bcb | ||
|
|
01054c9c79 | ||
|
|
8bd3ec2ba1 | ||
|
|
e08a9ea9ad | ||
|
|
1987398ec5 | ||
|
|
fa0fc9acb8 | ||
|
|
fa1c461c13 | ||
|
|
a99b05525d | ||
|
|
a337b21a4f | ||
|
|
1b96828667 | ||
|
|
7785c18c56 | ||
|
|
183709c522 | ||
|
|
458bf674ad | ||
|
|
3016edbe72 | ||
|
|
fa554a8e85 | ||
|
|
5b03f5c531 | ||
|
|
2acd10d7b0 | ||
|
|
a012f5bddb | ||
|
|
98796d4513 | ||
|
|
2bbf7d267a | ||
|
|
266d72a82f | ||
|
|
873c437235 | ||
|
|
15e0f3e8c6 | ||
|
|
af2a4d4a91 | ||
|
|
d4e2f23287 | ||
|
|
332bd868f5 | ||
|
|
60a83a51c3 | ||
|
|
79285bd63e | ||
|
|
3a941eff4a | ||
|
|
65adcec82f | ||
|
|
ffb6f39715 | ||
|
|
9a16269747 | ||
|
|
32f55a74b0 | ||
|
|
5320acf589 | ||
|
|
b9b2ac2ce3 | ||
|
|
ad041fc5d4 | ||
|
|
952f85c12d | ||
|
|
72d6241c84 | ||
|
|
aac3f1860f | ||
|
|
6be27682a8 | ||
|
|
8931169e00 | ||
|
|
72785c68d6 | ||
|
|
5c831d030a | ||
|
|
f17a924e7b | ||
|
|
2e542d8cae | ||
|
|
511a4ec475 | ||
|
|
b76a2e44ba | ||
|
|
d28b94f0cb | ||
|
|
c4766b2747 | ||
|
|
98bdf67468 | ||
|
|
dca57bebb7 | ||
|
|
de9a5f94c2 | ||
|
|
659a129f81 | ||
|
|
0c8bdf2ac2 | ||
|
|
3d2dcb437c | ||
|
|
22de54a9dc | ||
|
|
4b5ed886ce | ||
|
|
821dd26934 | ||
|
|
d6597098f1 | ||
|
|
4c1bc93f6f | ||
|
|
ef9b844c7f | ||
|
|
681ec04b85 | ||
|
|
7dd3289837 | ||
|
|
7e54a7e5a5 | ||
|
|
f050a9e889 | ||
|
|
ae2964c7c6 | ||
|
|
54daad3878 | ||
|
|
d7817e6fc6 | ||
|
|
de94f3d97f | ||
|
|
066884aed1 | ||
|
|
e7501185cd | ||
|
|
a08277adcd | ||
|
|
e8e69a1208 | ||
|
|
e16414b3ac | ||
|
|
2e42786091 | ||
|
|
b756aa0764 | ||
|
|
9654fd451f | ||
|
|
7d564ecdc9 | ||
|
|
d850dfd245 | ||
|
|
a6d5757627 | ||
|
|
ad8a3e5b45 | ||
|
|
5b78fe2721 | ||
|
|
7c0a395ff9 | ||
|
|
41f26975a9 | ||
|
|
085374198f | ||
|
|
586675c902 | ||
|
|
1679fc8675 | ||
|
|
9cc1dcf2a4 | ||
|
|
cc57692345 | ||
|
|
a0db8a24c2 | ||
|
|
e4be073f0a | ||
|
|
4ffefec469 | ||
|
|
db2432b5db | ||
|
|
7d29b456b8 | ||
|
|
8fbb647daa | ||
|
|
c28b8297ee | ||
|
|
4eb0dd7264 | ||
|
|
b3d6972803 | ||
|
|
0eab3c3940 | ||
|
|
4cbfb69f74 | ||
|
|
4603e7bb18 | ||
|
|
8d504cae44 | ||
|
|
0f35ece2af | ||
|
|
204cac7ebf | ||
|
|
06a51b6ca6 | ||
|
|
853bfcb130 | ||
|
|
6a1f5c0af5 | ||
|
|
91e6f8e4b9 | ||
|
|
bce90df49d | ||
|
|
58953671fe | ||
|
|
df527758b1 | ||
|
|
3cd55fdf35 | ||
|
|
25783573c6 | ||
|
|
041a186272 | ||
|
|
f5488bb4b2 | ||
|
|
86a38918d7 | ||
|
|
88f38f598b | ||
|
|
4aee6edbbd | ||
|
|
adcec93b02 | ||
|
|
79ff151624 | ||
|
|
27f32b7f9b | ||
|
|
1771f75c6c | ||
|
|
979c418e46 | ||
|
|
28f63259ab | ||
|
|
105a2262dc | ||
|
|
3615619f41 | ||
|
|
0782bfa52b | ||
|
|
ccd5565f75 | ||
|
|
e502155dfa | ||
|
|
9261b0079d | ||
|
|
4638f942b8 | ||
|
|
982b4ff3b2 | ||
|
|
46483bebcd | ||
|
|
e077a6bffe | ||
|
|
66dc193aeb | ||
|
|
39439aa838 | ||
|
|
018bd0a927 | ||
|
|
975ab6e7cf | ||
|
|
53c8975739 | ||
|
|
09176fc1b3 | ||
|
|
0f2582ff02 | ||
|
|
a217be14f9 | ||
|
|
e7b332c532 | ||
|
|
13382937d1 | ||
|
|
c364f1ee12 | ||
|
|
dd8c899737 | ||
|
|
d69fdaa04d | ||
|
|
16eced7bf1 | ||
|
|
1276e8868d | ||
|
|
7539fb4ced | ||
|
|
f24efd175e | ||
|
|
df40efd50d | ||
|
|
db5868d89b | ||
|
|
32796cad10 | ||
|
|
b6a965a67c | ||
|
|
6136f3ab95 | ||
|
|
d3e79633e1 | ||
|
|
b362098f63 | ||
|
|
35583c8d36 | ||
|
|
581bfd20e4 | ||
|
|
c5bbdfb7b1 | ||
|
|
bcccb46b7c | ||
|
|
916328da2b | ||
|
|
6ca0d616d4 | ||
|
|
137af44f81 | ||
|
|
0441fd3678 | ||
|
|
3abc3425cb | ||
|
|
2017f3debe | ||
|
|
4b08570727 | ||
|
|
1042ca7e52 | ||
|
|
52e3ed13e2 | ||
|
|
fb7257a1f5 | ||
|
|
83bf193218 | ||
|
|
f1c1c979c2 | ||
|
|
6cfb6e0c9c | ||
|
|
ef831235fe | ||
|
|
5286e9405d | ||
|
|
c11ea42644 | ||
|
|
d7c04145ee | ||
|
|
0d7a0132bb | ||
|
|
cad32636ce | ||
|
|
d125fcd35a | ||
|
|
88503bcc3b | ||
|
|
e68925a932 | ||
|
|
a6418d5028 | ||
|
|
04ebec0fa7 | ||
|
|
aa0f564aa1 | ||
|
|
3cbf6c9d6e | ||
|
|
a75de5fb90 | ||
|
|
1b66373a5d | ||
|
|
8786ac844c | ||
|
|
180dd5fb7f | ||
|
|
a53650d9da | ||
|
|
0d4d52d322 | ||
|
|
896155fab7 | ||
|
|
727ec4cf7d | ||
|
|
a52ee9ee22 | ||
|
|
94a9859391 | ||
|
|
d1755337a2 | ||
|
|
092c166f54 | ||
|
|
13f8eeb3ee | ||
|
|
36768471e5 | ||
|
|
3cfe04aa74 | ||
|
|
4965a3ea4b | ||
|
|
adc8a27f7a | ||
|
|
37d4dfb6b5 | ||
|
|
d887af0748 | ||
|
|
803ba1da4f | ||
|
|
78eaad614a | ||
|
|
749425808d | ||
|
|
5e299cd3d2 | ||
|
|
8ab57fc8ef | ||
|
|
3a8e45963f | ||
|
|
ff16446b0b | ||
|
|
82bcebe3de | ||
|
|
a790764a7a | ||
|
|
248e33e3c9 | ||
|
|
44931aa8f8 | ||
|
|
fb83adef25 | ||
|
|
08de13e9d2 | ||
|
|
f66ffde68d | ||
|
|
52ac71b972 | ||
|
|
27eaca8b79 | ||
|
|
63dce34396 | ||
|
|
3585da6b7f | ||
|
|
9e29739e66 | ||
|
|
82395e73ad | ||
|
|
0237713c3a | ||
|
|
7e0e8365bd | ||
|
|
fbd11fc595 | ||
|
|
bebaac64e1 | ||
|
|
1d232a725f | ||
|
|
fb4312738d | ||
|
|
918dd66dca | ||
|
|
6ceacee0f9 | ||
|
|
f1e81d176c | ||
|
|
8d18b2b92d | ||
|
|
4a04e468fd | ||
|
|
f8d1912098 | ||
|
|
0bd15b44f2 | ||
|
|
e4fb6933d2 | ||
|
|
33cf8f9404 | ||
|
|
1640390839 | ||
|
|
b01f28b9e2 | ||
|
|
62192cba6e | ||
|
|
586826d34c | ||
|
|
c7a55faf37 | ||
|
|
e81db46578 | ||
|
|
e036eebde8 | ||
|
|
dfa45c0da2 | ||
|
|
6692c7e9c4 | ||
|
|
671f33a7b8 | ||
|
|
0fee50d1a5 | ||
|
|
97d3363360 | ||
|
|
6eb3548192 | ||
|
|
e5a47b5592 | ||
|
|
6c3119bc33 | ||
|
|
7900032f30 | ||
|
|
a020cf7534 | ||
|
|
59f6c50df8 | ||
|
|
bbd6fdaa04 | ||
|
|
6a7136d5fb | ||
|
|
95860d4989 | ||
|
|
37a561eb53 | ||
|
|
ed0a2a203c | ||
|
|
fc3aca8223 | ||
|
|
6ebb38e12e | ||
|
|
51ca454eef | ||
|
|
fb100d719f | ||
|
|
cf1974f6b1 | ||
|
|
3f4a0aa1f3 | ||
|
|
0cc2d5559b | ||
|
|
b4ade026f1 | ||
|
|
102ca838b8 | ||
|
|
378ae4fbc1 | ||
|
|
00f079d705 | ||
|
|
54465adff2 | ||
|
|
29580d4252 | ||
|
|
25c3616a79 | ||
|
|
120399cc92 | ||
|
|
86e5ad85b7 | ||
|
|
04ad5e8936 | ||
|
|
9691a11076 | ||
|
|
fef3ab0b62 | ||
|
|
493660a296 | ||
|
|
73f634435a | ||
|
|
b17bba4af2 | ||
|
|
ba1a084899 | ||
|
|
0e5a97ae58 | ||
|
|
7a306fe32f | ||
|
|
ac7009d56c | ||
|
|
c68247f63b | ||
|
|
668a2c0f3e | ||
|
|
c435c7e764 | ||
|
|
4d36a4ebd7 | ||
|
|
703fc51d8e | ||
|
|
fb008578b4 | ||
|
|
adba0b972e | ||
|
|
c77b98d716 | ||
|
|
8eda182f24 | ||
|
|
15e0c175a3 | ||
|
|
bc953eebdd | ||
|
|
6238f97cb6 | ||
|
|
023924bca9 | ||
|
|
af6432aa67 | ||
|
|
6c37158bbc | ||
|
|
d030c92d63 | ||
|
|
efe100df9e | ||
|
|
a07ee709d2 | ||
|
|
60b77736b5 | ||
|
|
83ff85d227 | ||
|
|
f7b3a214f3 | ||
|
|
c1053096bd | ||
|
|
f2b85fa1c7 | ||
|
|
a48942bf39 | ||
|
|
c1d6160bd4 | ||
|
|
dbab69c453 | ||
|
|
09f0c96b9b | ||
|
|
641a589734 | ||
|
|
9bce70ed8d | ||
|
|
d00d1334ce | ||
|
|
fbe124ca54 | ||
|
|
f680b86130 | ||
|
|
dbc4e18bf8 | ||
|
|
924da0e84b | ||
|
|
38f14303d8 | ||
|
|
b896b73e5e | ||
|
|
81a65690f8 | ||
|
|
33f7d96e8f | ||
|
|
dcd549aebe | ||
|
|
8a4aee583c | ||
|
|
ea21923932 | ||
|
|
5ca266f137 | ||
|
|
b9f374c0c6 | ||
|
|
a32b9d8b51 | ||
|
|
c92b27f41b | ||
|
|
06bec5fb45 | ||
|
|
e0be85ccca | ||
|
|
0c052c9a37 | ||
|
|
a7bbc25851 | ||
|
|
d6fab1408a | ||
|
|
e14b84ff67 | ||
|
|
aba2d994e6 | ||
|
|
57c032e6cc | ||
|
|
f3fc8f5b35 | ||
|
|
ba909cf901 | ||
|
|
1e9a36ffa8 | ||
|
|
c6f357e447 | ||
|
|
2bcae546b3 | ||
|
|
291696607a | ||
|
|
87ba99f66b | ||
|
|
fc20268cb8 | ||
|
|
64a959dad9 | ||
|
|
111929593a | ||
|
|
23bd7c1c05 | ||
|
|
f99880a74a | ||
|
|
61bf5ac009 | ||
|
|
ef07d1556b | ||
|
|
dd5d1030b5 | ||
|
|
f480ff2e4d | ||
|
|
9c919ffa46 | ||
|
|
2b131f09a8 | ||
|
|
b165028e86 | ||
|
|
6e379181d9 | ||
|
|
edf8c9e501 | ||
|
|
f95f992d32 | ||
|
|
95cf34ab4c | ||
|
|
0cebf6d9c5 | ||
|
|
de6b8da6c4 | ||
|
|
03f24bb5cf | ||
|
|
6ef3968227 | ||
|
|
eb1a2268bb | ||
|
|
64193ae706 | ||
|
|
4682eb214a | ||
|
|
5a34b7ecc6 | ||
|
|
eb0b98d5f2 | ||
|
|
89db59a40d | ||
|
|
9209fd65a5 | ||
|
|
7dd874cec8 | ||
|
|
4a5d15535e | ||
|
|
c9a48736d6 | ||
|
|
8376f5c9fa | ||
|
|
1d94c75a78 | ||
|
|
d840e082e6 | ||
|
|
2ed954d307 | ||
|
|
7b815768e0 | ||
|
|
d89297b152 | ||
|
|
ff038428d8 | ||
|
|
7321eb881a | ||
|
|
648e423cc5 | ||
|
|
09da4db81f | ||
|
|
16fd2608fd | ||
|
|
c9c48d78bf | ||
|
|
50a8cbc0da | ||
|
|
188cb49b44 | ||
|
|
6da65b25b6 | ||
|
|
405cfc8f1f | ||
|
|
9daf83a1da | ||
|
|
f7811f5dc3 | ||
|
|
25ec58be3c | ||
|
|
61a843e824 | ||
|
|
14cb208ec2 | ||
|
|
c642649311 | ||
|
|
882c805b53 | ||
|
|
9cc7dbe9c9 | ||
|
|
3eac4ef5c9 | ||
|
|
f1faa71d6d | ||
|
|
a08bc46936 | ||
|
|
c6a56b52dc | ||
|
|
63c61340ac | ||
|
|
09f99ffb27 | ||
|
|
3cc3a73d97 | ||
|
|
d8a73cbd03 | ||
|
|
624f5ba0ec | ||
|
|
ac81ed3adb | ||
|
|
5064a8eac0 | ||
|
|
a4c6517d06 | ||
|
|
7ebc5454f4 | ||
|
|
35e6a2fdb8 | ||
|
|
69336fa5f1 | ||
|
|
2cbb955e49 | ||
|
|
42042e6811 | ||
|
|
f8f669b895 | ||
|
|
7743f35972 | ||
|
|
db01233520 | ||
|
|
fa1daf50a7 | ||
|
|
678eb8ab76 | ||
|
|
c46b5ed646 | ||
|
|
f8945b6325 | ||
|
|
3c67f6a457 | ||
|
|
9868143696 | ||
|
|
b51eb4bd72 | ||
|
|
62619a9777 | ||
|
|
d37ccbffa3 | ||
|
|
b3ecc40cf1 | ||
|
|
5b76d0c226 | ||
|
|
9eb6de403f | ||
|
|
d104357d40 | ||
|
|
775435c025 | ||
|
|
24f31b6797 | ||
|
|
45f69d2fbe | ||
|
|
af5f75aa77 | ||
|
|
74494b0b3a | ||
|
|
94673707e6 | ||
|
|
e204910730 | ||
|
|
afe476c2e3 | ||
|
|
dfe8eb37ce | ||
|
|
88e8837587 | ||
|
|
f218a4e2d2 | ||
|
|
685961a8c6 | ||
|
|
dced70a8d0 | ||
|
|
f4f683a469 | ||
|
|
63fe3345a7 | ||
|
|
01e99fad1e | ||
|
|
0074ee3149 | ||
|
|
ad361abc4c | ||
|
|
103f52bb8a | ||
|
|
c2ec244b84 | ||
|
|
e71f9bb79f | ||
|
|
bf75a21deb | ||
|
|
1bba874895 | ||
|
|
01f5142b00 | ||
|
|
620d48ca0c | ||
|
|
e8c5c2f648 | ||
|
|
71eb19bf51 | ||
|
|
7857c1a66b | ||
|
|
1e3ae95b7e | ||
|
|
1ff38cdf6a | ||
|
|
4147dd218d | ||
|
|
e68a3a6123 | ||
|
|
6368278005 | ||
|
|
edb61cc434 | ||
|
|
743406998c | ||
|
|
f56c0bc034 | ||
|
|
988e20cd53 | ||
|
|
726c9e83d2 | ||
|
|
e7af42c758 | ||
|
|
7c5d71ebf6 | ||
|
|
d659bc8762 | ||
|
|
9f2a621328 | ||
|
|
fae2dd9885 | ||
|
|
c673d7cd9b | ||
|
|
1c8bddf3ca | ||
|
|
ab1cf67432 | ||
|
|
1097003f6f | ||
|
|
5faa300c5e | ||
|
|
7df347d9a5 | ||
|
|
7ed8a6ae3c | ||
|
|
ff84b96480 | ||
|
|
64347f2c79 | ||
|
|
1af7cde1a8 | ||
|
|
4ab9592924 | ||
|
|
6f01d458d5 | ||
|
|
6f9013297a |
@@ -4,6 +4,7 @@ AlwaysBreakAfterDefinitionReturnType: All
|
||||
BreakBeforeBinaryOperators: None
|
||||
BinPackParameters: false
|
||||
SpaceAfterCStyleCast: true
|
||||
PointerAlignment: Right
|
||||
# Our column limit is actually 80, but setting that results in clang-format
|
||||
# making a lot of dubious hanging-indent choices; disable it and assume the
|
||||
# developer will line wrap appropriately. clang-format will still check
|
||||
|
||||
@@ -3,6 +3,7 @@ include:
|
||||
file: 'flatpak/flatpak_ci_initiative.yml'
|
||||
|
||||
stages:
|
||||
- check
|
||||
- build
|
||||
- analysis
|
||||
- docs
|
||||
@@ -21,12 +22,12 @@ stages:
|
||||
|
||||
# Common variables
|
||||
variables:
|
||||
COMMON_MESON_FLAGS: "-Dwerror=true -Dglib:werror=false -Dpango:werror=false -Dgtk-doc:werror=false -Dwayland-protocols:werror=false -Dsysprof:werror=false"
|
||||
COMMON_MESON_FLAGS: "-Dwerror=true -Dglib:werror=false -Dpango:werror=false -Dgtk-doc:werror=false -Dwayland-protocols:werror=false -Dsysprof:werror=false -Dwayland:werror=false"
|
||||
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
|
||||
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled"
|
||||
MESON_TEST_TIMEOUT_MULTIPLIER: 3
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v38"
|
||||
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
|
||||
FLATPAK_IMAGE: "quay.io/gnome_infrastructure/gnome-runtime-images:gnome-master"
|
||||
|
||||
.only-default:
|
||||
only:
|
||||
@@ -37,7 +38,7 @@ variables:
|
||||
style-check-diff:
|
||||
extends: .only-default
|
||||
image: $FEDORA_IMAGE
|
||||
stage: .pre
|
||||
stage: check
|
||||
allow_failure: true
|
||||
script:
|
||||
- .gitlab-ci/run-style-check-diff.sh
|
||||
@@ -109,6 +110,29 @@ release-build:
|
||||
- ninja -C _build
|
||||
- .gitlab-ci/run-tests.sh _build x11
|
||||
|
||||
fedora-mingw64:
|
||||
extends: .build-fedora-default
|
||||
stage: build
|
||||
needs: []
|
||||
before_script:
|
||||
- sudo dnf install -y
|
||||
mingw64-filesystem
|
||||
mingw64-gcc
|
||||
mingw64-binutils
|
||||
mingw64-cairo
|
||||
mingw64-gdk-pixbuf
|
||||
mingw64-gstreamer1-plugins-bad-free
|
||||
mingw64-glib2
|
||||
mingw64-libepoxy
|
||||
mingw64-pango
|
||||
# mingw64-graphene (rawhide)
|
||||
script:
|
||||
- .gitlab-ci/show-info-linux.sh
|
||||
- meson subprojects update
|
||||
- mkdir _build && cd _build
|
||||
- mingw64-meson -Dintrospection=disabled -Dgraphene:introspection=disabled
|
||||
- ninja
|
||||
|
||||
installed-tests:
|
||||
extends: .build-fedora-default
|
||||
stage: build
|
||||
@@ -168,6 +192,7 @@ macos:
|
||||
only:
|
||||
- branches@GNOME/gtk
|
||||
stage: build
|
||||
allow_failure: true
|
||||
tags:
|
||||
- macos
|
||||
needs: []
|
||||
@@ -269,6 +294,18 @@ flatpak-main:icon-browser:
|
||||
variables:
|
||||
APPID: org.gtk.IconBrowser4
|
||||
|
||||
flatpak-manual:node-editor:
|
||||
extends: .flatpak-manual
|
||||
needs: []
|
||||
variables:
|
||||
APPID: org.gtk.gtk4.NodeEditor
|
||||
|
||||
flatpak-main:node-editor:
|
||||
extends: .flatpak-main
|
||||
needs: []
|
||||
variables:
|
||||
APPID: org.gtk.gtk4.NodeEditor
|
||||
|
||||
# Publish the demo apps to the GNOME Nightly repo
|
||||
# https://wiki.gnome.org/Apps/Nightly
|
||||
# https://gitlab.gnome.org/GNOME/Initiatives/-/wikis/DevOps-with-Flatpak
|
||||
@@ -287,6 +324,11 @@ nightly icon-browser:
|
||||
dependencies: ['flatpak-main:icon-browser']
|
||||
needs: ['flatpak-main:icon-browser']
|
||||
|
||||
nightly node-editor:
|
||||
extends: '.publish_nightly'
|
||||
dependencies: ['flatpak-main:node-editor']
|
||||
needs: ['flatpak-main:node-editor']
|
||||
|
||||
static-scan:
|
||||
image: $FEDORA_IMAGE
|
||||
stage: analysis
|
||||
|
||||
@@ -16,10 +16,9 @@ flatpak-builder \
|
||||
flatpak build ${builddir} meson \
|
||||
--prefix=/app \
|
||||
--libdir=/app/lib \
|
||||
--buildtype=release \
|
||||
--buildtype=debugoptimized \
|
||||
-Dx11-backend=true \
|
||||
-Dwayland-backend=true \
|
||||
-Dprint-backends=file \
|
||||
-Dbuild-tests=false \
|
||||
-Dbuild-examples=false \
|
||||
-Dintrospection=disabled \
|
||||
|
||||
@@ -2,25 +2,43 @@
|
||||
|
||||
set -e
|
||||
|
||||
# We need to add a new remote for the upstream main, since this script could
|
||||
# be running in a personal fork of the repository which has out of date branches.
|
||||
if [ "${CI_PROJECT_NAMESPACE}" != "GNOME" ]; then
|
||||
echo "Retrieving the current upstream repository from ${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}..."
|
||||
ancestor_horizon=31 # days (one month)
|
||||
|
||||
# Recently, git is picky about directory ownership. Tell it not to worry.
|
||||
git config --global --add safe.directory "$PWD"
|
||||
|
||||
# We need to add a new remote for the upstream target branch, since this script
|
||||
# could be running in a personal fork of the repository which has out of date
|
||||
# branches.
|
||||
#
|
||||
# Limit the fetch to a certain date horizon to limit the amount of data we get.
|
||||
# If the branch was forked from origin/main before this horizon, it should
|
||||
# probably be rebased.
|
||||
if ! git ls-remote --exit-code upstream >/dev/null 2>&1 ; then
|
||||
git remote add upstream https://gitlab.gnome.org/GNOME/gtk.git
|
||||
git fetch upstream
|
||||
ORIGIN="upstream"
|
||||
else
|
||||
echo "Reusing the existing repository on ${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}"
|
||||
ORIGIN="origin"
|
||||
fi
|
||||
|
||||
# Work out the newest common ancestor between the detached HEAD that this CI job
|
||||
# has checked out, and the upstream target branch (which will typically be
|
||||
# `upstream/main` or `upstream/gtk-3-24`).
|
||||
#
|
||||
# `${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}` is only defined if we’re running in
|
||||
# a merge request pipeline; fall back to `${CI_DEFAULT_BRANCH}` otherwise.
|
||||
newest_common_ancestor_sha=$(diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "${ORIGIN}/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:-${CI_DEFAULT_BRANCH}}") <(git rev-list --first-parent HEAD) | head -1)
|
||||
# `upstream/main` or `upstream/glib-2-62`).
|
||||
# `${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}` or `${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME}`
|
||||
# are only defined if we’re running in a merge request pipeline,
|
||||
# fall back to `${CI_DEFAULT_BRANCH}` or `${CI_COMMIT_BRANCH}` respectively
|
||||
# otherwise.
|
||||
|
||||
source_branch="${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME:-${CI_COMMIT_BRANCH}}"
|
||||
target_branch="${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:-${CI_DEFAULT_BRANCH}}"
|
||||
git fetch --shallow-since="$(date --date="${ancestor_horizon} days ago" +%Y-%m-%d)" origin "${source_branch}"
|
||||
git fetch --shallow-since="$(date --date="${ancestor_horizon} days ago" +%Y-%m-%d)" upstream "${target_branch}"
|
||||
|
||||
newest_common_ancestor_sha=$(git merge-base upstream/${target_branch} origin/${source_branch})
|
||||
if [ -z "${newest_common_ancestor_sha}" ]; then
|
||||
echo "Couldn’t find common ancestor with upstream main branch. This typically"
|
||||
echo "happens if you branched from main a long time ago. Please update"
|
||||
echo "your clone, rebase, and re-push your branch."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git diff -U0 --no-color "${newest_common_ancestor_sha}" | .gitlab-ci/clang-format-diff.py -binary "clang-format" -p1
|
||||
exit_status=$?
|
||||
|
||||
@@ -36,7 +54,7 @@ exit_status=$?
|
||||
echo ""
|
||||
echo "Note that clang-format output is advisory and cannot always match the"
|
||||
echo "GTK coding style, documented at:"
|
||||
echo " https://gitlab.gnome.org/GNOME/gtk/blob/main/docs/CODING-STYLE"
|
||||
echo " https://gitlab.gnome.org/GNOME/gtk/blob/main/docs/CODING-STYLE.md"
|
||||
echo "Warnings from this tool can be ignored in favour of the documented "
|
||||
echo "coding style, or in favour of matching the style of existing"
|
||||
echo "surrounding code."
|
||||
|
||||
@@ -28,7 +28,7 @@ pacman --noconfirm -S --needed \
|
||||
mingw-w64-$MSYS2_ARCH-graphene \
|
||||
mingw-w64-$MSYS2_ARCH-json-glib \
|
||||
mingw-w64-$MSYS2_ARCH-libepoxy \
|
||||
mingw-w64-$MSYS2_ARCH-pango2 \
|
||||
mingw-w64-$MSYS2_ARCH-pango \
|
||||
mingw-w64-$MSYS2_ARCH-fribidi \
|
||||
mingw-w64-$MSYS2_ARCH-gst-plugins-bad-libs \
|
||||
mingw-w64-$MSYS2_ARCH-shared-mime-info \
|
||||
@@ -38,25 +38,6 @@ mkdir -p _ccache
|
||||
export CCACHE_BASEDIR="$(pwd)"
|
||||
export CCACHE_DIR="${CCACHE_BASEDIR}/_ccache"
|
||||
|
||||
# https://gitlab.gnome.org/GNOME/gtk/-/issues/2243
|
||||
# https://gitlab.gnome.org/GNOME/gtk/-/issues/3002
|
||||
|
||||
if ! pkg-config --atleast-version=2.66.0 glib-2.0; then
|
||||
git clone https://gitlab.gnome.org/GNOME/glib.git _glib
|
||||
meson setup _glib_build _glib
|
||||
meson compile -C _glib_build
|
||||
meson install -C _glib_build
|
||||
fi
|
||||
pkg-config --modversion glib-2.0
|
||||
|
||||
if ! pkg-config --atleast-version=1.50.0 pango; then
|
||||
git clone https://gitlab.gnome.org/GNOME/pango.git _pango
|
||||
meson setup _pango_build _pango
|
||||
meson compile -C _pango_build
|
||||
meson install -C _pango_build
|
||||
fi
|
||||
pkg-config --modversion pango
|
||||
|
||||
# Build
|
||||
ccache --zero-stats
|
||||
ccache --show-stats
|
||||
|
||||
308
NEWS
308
NEWS
@@ -1,3 +1,311 @@
|
||||
Overview of Changes in 4.9.1, dd-mm-yyyy
|
||||
========================================
|
||||
|
||||
Note that deprecations are an early outlook
|
||||
at changes that will appear in an eventual
|
||||
GTK 5 release, which is still far away.
|
||||
|
||||
* GtkTreeView, GtkIconView, GtkComboBox and
|
||||
auxiliary classes have been deprecated
|
||||
|
||||
* GtkEntryCompletion has been deprecated
|
||||
|
||||
* GtkStyleContext has been deprecated
|
||||
|
||||
* gtk_render_ and gtk_snapshot_render_ APIs
|
||||
have been deprecated
|
||||
|
||||
* GtkAppChooser widgets hae been deprecated
|
||||
|
||||
* GtkMountOperation:
|
||||
- Fix the dialog to look reasonable
|
||||
- Make it work under non-X11
|
||||
|
||||
* GtkStringSorter:
|
||||
- Support different collation methods
|
||||
|
||||
* Accessibility:
|
||||
- Introduce GtkAccessibleRange and implement it
|
||||
|
||||
* Debugging:
|
||||
- Unify formatting for debug output
|
||||
- Make make debug options available in
|
||||
non-debug builds
|
||||
|
||||
* Translation updates:
|
||||
Abkhazian
|
||||
Basque
|
||||
Bulgarian
|
||||
Croatian
|
||||
Friulian
|
||||
Georgian
|
||||
German
|
||||
Hungarian
|
||||
Russian
|
||||
Turkish
|
||||
|
||||
|
||||
Overview of Changes in 4.8.1, 16-09-2022
|
||||
========================================
|
||||
|
||||
* Input:
|
||||
- Fix problems with input method interactions that caused
|
||||
dead keys not to work
|
||||
- Accept single-key compose sequences (these are used with
|
||||
some keyboard layouts)
|
||||
|
||||
* GtkColumnView:
|
||||
- Flip column order in right-to-left context
|
||||
|
||||
* GtkGridView:
|
||||
- Fix problems with rubberbanding
|
||||
|
||||
* GtkFileChooser:
|
||||
- Fix positioning of popovers in the places view
|
||||
- Make ~ and . keyboard shortcuts work again
|
||||
|
||||
* gsk:
|
||||
- Make glyph upload more similar to icons
|
||||
|
||||
* Make file transfer via portals work, this fixes file
|
||||
copy/paste and dnd in flatpaks
|
||||
|
||||
* Translation updates:
|
||||
Catalan
|
||||
Chinese (China)
|
||||
Chinese (Taiwan)
|
||||
Latvian
|
||||
|
||||
|
||||
Overview of Changes in 4.8.0, 06-09-2022
|
||||
========================================
|
||||
|
||||
* GtkTreeView:
|
||||
- Fix a problem with scrolling animations
|
||||
- Fix some event handling problems
|
||||
- Drop unreachable code
|
||||
|
||||
* GtkText:
|
||||
- Respect the no-emoji input hint fully
|
||||
|
||||
* GtkEmojiChooser:
|
||||
- Fix arrow key navigation
|
||||
|
||||
* GtkFontChooser:
|
||||
- Improve the handling of OpenType font features
|
||||
|
||||
* GtkTreeListModel:
|
||||
- Fix handling of collapsed child nodes
|
||||
|
||||
* GtkInscription:
|
||||
- Fix accessible name
|
||||
|
||||
* Theme:
|
||||
- Fix placeholder text in HighContrast
|
||||
|
||||
* Increase the memory limit for the jpeg loader to 300M
|
||||
|
||||
* Miscellaneous memory leak fixes
|
||||
|
||||
* Wayland:
|
||||
- Refator handling of text protocol client updates
|
||||
|
||||
* Windows:
|
||||
- Support high-resolution scroll wheel events
|
||||
- Generate GdkWin32.gir
|
||||
- Implement color picking
|
||||
|
||||
* Translation updates
|
||||
Abkhazian
|
||||
Basque
|
||||
Brazilian Portuguese
|
||||
Bulgarian
|
||||
Catalan
|
||||
Chinese (China)
|
||||
Croatian
|
||||
Czech
|
||||
Danish
|
||||
Dutch
|
||||
Galician
|
||||
Georgian
|
||||
German
|
||||
Hungarian
|
||||
Icelandic
|
||||
Indonesian
|
||||
Korean
|
||||
Latvian
|
||||
Lithuanian
|
||||
Persian
|
||||
Polish
|
||||
Portuguese
|
||||
Russian
|
||||
Serbian
|
||||
Spanish
|
||||
Swedish
|
||||
Turkish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.7.2, 10-08-2022
|
||||
========================================
|
||||
|
||||
* GtkTextView:
|
||||
- Fix child positioning with gutters
|
||||
|
||||
* GtkText:
|
||||
- Update placeholder visibility when necessary
|
||||
|
||||
* GtkPicture:
|
||||
- Add a content-fit property
|
||||
|
||||
* GtkPopover:
|
||||
- Fix a size allocation problem with the arrow
|
||||
|
||||
* GtkTreeView:
|
||||
- Fix a problem with DND
|
||||
|
||||
* GtkTreePopover:
|
||||
- Support scrolling
|
||||
|
||||
* GtkGridView:
|
||||
- Fix issues with rubberband selection
|
||||
|
||||
* GtkLabel:
|
||||
- Add a tabs property
|
||||
|
||||
* GtkSnapshot:
|
||||
- Make GtkSnapshot work from bindings
|
||||
|
||||
* GtkScrolledWindow:
|
||||
- Scroll at a reasonable speed
|
||||
|
||||
* GtkPaned:
|
||||
- Avoid an infinite loop
|
||||
|
||||
* GtkWindow:
|
||||
- Improve generation and handling of crossing events
|
||||
|
||||
* CSS:
|
||||
- Fix handling of certain transform values
|
||||
|
||||
* Media support:
|
||||
- Add audio support to the ffmpeg backend
|
||||
- Avoid oom with pathological jpeg images
|
||||
|
||||
* GDK:
|
||||
- Fix handling of touchpad hold events
|
||||
- Add support for hi-resolution scroll events
|
||||
|
||||
* X11:
|
||||
- Fix preferred action for DND
|
||||
|
||||
* Windows:
|
||||
- Fix DND
|
||||
|
||||
* List models:
|
||||
- Fix items-changed emission
|
||||
- Add more list model tests
|
||||
|
||||
* Demos:
|
||||
- Add a winning sound to game demos
|
||||
- Make app icons work uninstalled
|
||||
|
||||
* Translation updates:
|
||||
Abkhazian
|
||||
Basque
|
||||
Catalan
|
||||
Georgian
|
||||
German
|
||||
Indonesian
|
||||
Occitan
|
||||
Persian
|
||||
Portuguese
|
||||
Russian
|
||||
Spanish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.7.1, 12-07-2022
|
||||
========================================
|
||||
|
||||
* GtkInscription:
|
||||
- A new label-like widget for use in list views
|
||||
|
||||
* GtkColorChooser:
|
||||
- Style improvements
|
||||
|
||||
* GtkFontChooser:
|
||||
- Improve support for OpenType features a bit
|
||||
|
||||
* GtkLabel:
|
||||
- Allow selectable labels to be activated via mnemonic
|
||||
|
||||
* GtkTextView:
|
||||
- Implement GetCharacterExtents for accessibility
|
||||
|
||||
* GtkStack:
|
||||
- Fix a poblem with stack page accessibility
|
||||
|
||||
* GtkListView:
|
||||
- Cull listitems that are out of view
|
||||
- Make all our list models implement ::n-items and
|
||||
::item-type properties
|
||||
|
||||
* Translations:
|
||||
- Stop translating property nicks and blurbs
|
||||
- Fix extracting translations from ui files
|
||||
|
||||
* Debugging:
|
||||
- Support GTK_DEBUG=invert-text-dir
|
||||
- Allow inspecting inspectors
|
||||
- Replace GTK_USE_PORTAL with GDK_DEBUG=portals
|
||||
- Improve responsiveness of the inspector
|
||||
|
||||
* CSS:
|
||||
- Allow fractional letterspacing
|
||||
|
||||
* Theme:
|
||||
- Improve legibility of selectable labels
|
||||
|
||||
* Demos:
|
||||
- Improve the font features demo
|
||||
- Add demos for GtkInscription
|
||||
|
||||
* Wayland:
|
||||
- Freeze popups when hidden
|
||||
- Only send smooth scroll events for tablet tools
|
||||
- Make scaled cursor image have the right size
|
||||
- Fix problems with the activation protocol
|
||||
- Don't force the HighContrast icon theme
|
||||
- Support xdg_toplevel.bounds
|
||||
|
||||
* X11:
|
||||
- Always update the shadoe size
|
||||
|
||||
* Windows:
|
||||
- Improve touchpad support by using DirectManipulation
|
||||
- Add more directories to the builtin hicolor icon theme
|
||||
|
||||
* Translation updates:
|
||||
Basque
|
||||
Catalan
|
||||
Chinese (China)
|
||||
Galician
|
||||
German
|
||||
Lithuanian
|
||||
Nepali
|
||||
Occitan
|
||||
Persian
|
||||
Polish
|
||||
Portuguese
|
||||
Russian
|
||||
Serbian
|
||||
Spanish
|
||||
Swedish
|
||||
Turkish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.7.0, 07-05-2022
|
||||
========================================
|
||||
|
||||
|
||||
@@ -54,8 +54,7 @@
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib",
|
||||
"-Dtests=false",
|
||||
"-Dbenchmarks=false"
|
||||
"-Dtests=false"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
@@ -105,8 +104,8 @@
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://boostorg.jfrog.io/artifactory/main/release/1.69.0/source/boost_1_69_0.tar.bz2",
|
||||
"sha256": "8f32d4617390d1c2d16f26a27ab60d97807b35440d45891fa340fc2648b04406"
|
||||
"url": "https://boostorg.jfrog.io/artifactory/main/release/1.79.0/source/boost_1_79_0.tar.bz2",
|
||||
"sha256": "475d589d51a7f8b3ba2ba4eda022b170e562ca3b760ee922c146b6c65856ef39"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -186,7 +185,7 @@
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib",
|
||||
"-Denable_vulkan=no",
|
||||
"-Dvulkan=disabled",
|
||||
"-Dbuildtype=debugoptimized",
|
||||
"-Dprofile=devel"
|
||||
],
|
||||
|
||||
@@ -54,8 +54,7 @@
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib",
|
||||
"-Dtests=false",
|
||||
"-Dbenchmarks=false"
|
||||
"-Dtests=false"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
@@ -115,7 +114,7 @@
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib",
|
||||
"-Denable_vulkan=no",
|
||||
"-Dvulkan=disabled",
|
||||
"-Dbuildtype=debugoptimized",
|
||||
"-Dprofile=devel"
|
||||
],
|
||||
|
||||
@@ -54,8 +54,7 @@
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib",
|
||||
"-Dtests=false",
|
||||
"-Dbenchmarks=false"
|
||||
"-Dtests=false"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
@@ -115,7 +114,7 @@
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib",
|
||||
"-Denable_vulkan=no",
|
||||
"-Dvulkan=disabled",
|
||||
"-Dbuildtype=debugoptimized",
|
||||
"-Dprofile=devel"
|
||||
],
|
||||
|
||||
138
build-aux/flatpak/org.gtk.gtk4.NodeEditor.json
Normal file
138
build-aux/flatpak/org.gtk.gtk4.NodeEditor.json
Normal file
@@ -0,0 +1,138 @@
|
||||
{
|
||||
"app-id" : "org.gtk.gtk4.NodeEditor",
|
||||
"runtime" : "org.gnome.Platform",
|
||||
"runtime-version" : "master",
|
||||
"sdk" : "org.gnome.Sdk",
|
||||
"command" : "gtk4-node-editor",
|
||||
"tags" : [
|
||||
"devel",
|
||||
"development",
|
||||
"nightly"
|
||||
],
|
||||
"desktop-file-name-prefix" : "(Development) ",
|
||||
"finish-args" : [
|
||||
"--device=dri",
|
||||
"--share=ipc",
|
||||
"--socket=fallback-x11",
|
||||
"--socket=wayland",
|
||||
"--talk-name=org.gtk.vfs",
|
||||
"--talk-name=org.gtk.vfs.*"
|
||||
],
|
||||
"cleanup" : [
|
||||
"/include",
|
||||
"/lib/pkgconfig",
|
||||
"/share/pkgconfig",
|
||||
"/share/aclocal",
|
||||
"/man",
|
||||
"/share/man",
|
||||
"/share/gtk-doc",
|
||||
"*.la",
|
||||
".a",
|
||||
"/lib/girepository-1.0",
|
||||
"/share/gir-1.0",
|
||||
"/share/doc"
|
||||
],
|
||||
"modules" : [
|
||||
{
|
||||
"name" : "wayland",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"-Ddocumentation=false"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git",
|
||||
"branch" : "main"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "graphene",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib",
|
||||
"-Dtests=false"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/ebassi/graphene.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "libsass",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/lazka/libsass.git",
|
||||
"branch" : "meson"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "sassc",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/lazka/sassc.git",
|
||||
"branch" : "meson"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "pango",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/pango.git",
|
||||
"branch" : "main"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "gtk",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib",
|
||||
"-Dvulkan=disabled",
|
||||
"-Dbuildtype=debugoptimized",
|
||||
"-Dprofile=devel"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/gtk.git",
|
||||
"branch" : "main"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"build-options" : {
|
||||
"env" : {
|
||||
"DBUS_SESSION_BUS_ADDRESS" : "''",
|
||||
"GSK_RENDERER" : "opengl",
|
||||
"GDK_DEBUG" : "vulkan-disable",
|
||||
"G_ENABLE_DEBUG" : "true"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
if 'DESTDIR' not in os.environ:
|
||||
gtk_api_version = sys.argv[1]
|
||||
gtk_abi_version = sys.argv[2]
|
||||
gtk_libdir = sys.argv[3]
|
||||
gtk_datadir = sys.argv[4]
|
||||
gtk_bindir = sys.argv[5]
|
||||
|
||||
gtk_moduledir = os.path.join(gtk_libdir, 'gtk-' + gtk_api_version, gtk_abi_version)
|
||||
gtk_printmodule_dir = os.path.join(gtk_moduledir, 'printbackends')
|
||||
gtk_mediamodule_dir = os.path.join(gtk_moduledir, 'media')
|
||||
|
||||
print('Compiling GSettings schemas...')
|
||||
glib_compile_schemas = subprocess.check_output(['pkg-config',
|
||||
'--variable=glib_compile_schemas',
|
||||
'gio-2.0']).strip()
|
||||
if not os.path.exists(glib_compile_schemas):
|
||||
# pkg-config variables only available since GLib 2.62.0.
|
||||
glib_compile_schemas = 'glib-compile-schemas'
|
||||
subprocess.call([glib_compile_schemas,
|
||||
os.path.join(gtk_datadir, 'glib-2.0', 'schemas')])
|
||||
|
||||
print('Updating icon cache...')
|
||||
update_icon_cache = os.path.join(gtk_bindir, 'gtk4-update-icon-cache')
|
||||
subprocess.call([update_icon_cache, '-q', '-t' ,'-f',
|
||||
os.path.join(gtk_datadir, 'icons', 'hicolor')])
|
||||
|
||||
print('Updating module cache for print backends...')
|
||||
os.makedirs(gtk_printmodule_dir, exist_ok=True)
|
||||
gio_querymodules = subprocess.check_output(['pkg-config',
|
||||
'--variable=gio_querymodules',
|
||||
'gio-2.0']).strip()
|
||||
if not os.path.exists(gio_querymodules):
|
||||
# pkg-config variables only available since GLib 2.62.0.
|
||||
gio_querymodules = 'gio-querymodules'
|
||||
subprocess.call([gio_querymodules, gtk_printmodule_dir])
|
||||
|
||||
print('Updating module cache for media backends...')
|
||||
os.makedirs(gtk_mediamodule_dir, exist_ok=True)
|
||||
subprocess.call([gio_querymodules, gtk_mediamodule_dir])
|
||||
@@ -361,11 +361,11 @@ save_cb (GtkWidget *button,
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_window_finalize (GObject *object)
|
||||
constraint_editor_window_dispose (GObject *object)
|
||||
{
|
||||
//ConstraintEditorWindow *self = (ConstraintEditorWindow *)object;
|
||||
gtk_widget_dispose_template (GTK_WIDGET (object), CONSTRAINT_EDITOR_WINDOW_TYPE);
|
||||
|
||||
G_OBJECT_CLASS (constraint_editor_window_parent_class)->finalize (object);
|
||||
G_OBJECT_CLASS (constraint_editor_window_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static int child_counter;
|
||||
@@ -497,7 +497,7 @@ constraint_editor_window_class_init (ConstraintEditorWindowClass *class)
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
object_class->finalize = constraint_editor_window_finalize;
|
||||
object_class->dispose = constraint_editor_window_dispose;
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class,
|
||||
"/org/gtk/gtk4/constraint-editor/constraint-editor-window.ui");
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
#include "constraint-editor.h"
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
struct _ConstraintEditor
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
@@ -607,10 +609,11 @@ constraint_editor_dispose (GObject *object)
|
||||
{
|
||||
ConstraintEditor *self = (ConstraintEditor *)object;
|
||||
|
||||
g_clear_pointer (&self->grid, gtk_widget_unparent);
|
||||
g_clear_object (&self->model);
|
||||
g_clear_object (&self->constraint);
|
||||
|
||||
gtk_widget_dispose_template (GTK_WIDGET (object), CONSTRAINT_EDITOR_TYPE);
|
||||
|
||||
G_OBJECT_CLASS (constraint_editor_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
#include "guide-editor.h"
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
struct _GuideEditor
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
@@ -294,9 +296,10 @@ guide_editor_dispose (GObject *object)
|
||||
{
|
||||
GuideEditor *self = (GuideEditor *)object;
|
||||
|
||||
g_clear_pointer (&self->grid, gtk_widget_unparent);
|
||||
g_clear_object (&self->guide);
|
||||
|
||||
gtk_widget_dispose_template (GTK_WIDGET (self), GUIDE_EDITOR_TYPE);
|
||||
|
||||
G_OBJECT_CLASS (guide_editor_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,303 +0,0 @@
|
||||
#include "fontcolors.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <hb-ot.h>
|
||||
|
||||
#include "rangeedit.h"
|
||||
|
||||
enum {
|
||||
PROP_FONT_MAP = 1,
|
||||
PROP_FONT_DESC,
|
||||
PROP_PALETTE,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
struct _FontColors
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
GtkGrid *label;
|
||||
GtkGrid *grid;
|
||||
Pango2FontDescription *font_desc;
|
||||
GSimpleAction *reset_action;
|
||||
gboolean has_colors;
|
||||
char *palette;
|
||||
GtkCheckButton *default_check;
|
||||
|
||||
Pango2FontMap *font_map;
|
||||
};
|
||||
|
||||
struct _FontColorsClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (FontColors, font_colors, GTK_TYPE_WIDGET);
|
||||
|
||||
static Pango2Font *
|
||||
get_font (FontColors *self)
|
||||
{
|
||||
Pango2Context *context;
|
||||
Pango2Font *font;
|
||||
|
||||
context = pango2_context_new_with_font_map (self->font_map);
|
||||
font = pango2_context_load_font (context, self->font_desc);
|
||||
g_object_unref (context);
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
static void
|
||||
palette_changed (GtkCheckButton *button,
|
||||
FontColors *self)
|
||||
{
|
||||
g_free (self->palette);
|
||||
self->palette = g_strdup ((const char *) g_object_get_data (G_OBJECT (button), "palette"));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PALETTE]);
|
||||
}
|
||||
|
||||
static void
|
||||
update_colors (FontColors *self)
|
||||
{
|
||||
Pango2Font *font;
|
||||
hb_font_t *hb_font;
|
||||
hb_face_t *hb_face;
|
||||
GtkWidget *child;
|
||||
GtkWidget *check;
|
||||
unsigned int n_colors;
|
||||
hb_color_t *colors;
|
||||
GtkWidget *box;
|
||||
|
||||
g_object_ref (self->label);
|
||||
|
||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (self->grid))))
|
||||
gtk_grid_remove (self->grid, child);
|
||||
|
||||
gtk_grid_attach (self->grid, GTK_WIDGET (self->label), 0, -4, 2, 1);
|
||||
g_object_unref (self->label);
|
||||
|
||||
self->default_check = NULL;
|
||||
|
||||
font = get_font (self);
|
||||
hb_font = pango2_font_get_hb_font (font);
|
||||
hb_face = hb_font_get_face (hb_font);
|
||||
|
||||
self->has_colors = hb_ot_color_has_palettes (hb_face);
|
||||
gtk_widget_set_visible (GTK_WIDGET (self), self->has_colors);
|
||||
if (!self->has_colors)
|
||||
{
|
||||
g_simple_action_set_enabled (self->reset_action, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
|
||||
gtk_grid_attach (self->grid, box, 0, -3, 2, 1);
|
||||
|
||||
check = gtk_check_button_new_with_label ("Default");
|
||||
g_object_set_data (G_OBJECT (check), "palette", (gpointer)"default");
|
||||
if (g_strcmp0 ("default", self->palette) == 0)
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (check), TRUE);
|
||||
g_signal_connect (check, "toggled", G_CALLBACK (palette_changed), self);
|
||||
gtk_box_append (GTK_BOX (box), check);
|
||||
self->default_check = GTK_CHECK_BUTTON (check);
|
||||
|
||||
check = gtk_check_button_new_with_label ("Light");
|
||||
g_object_set_data (G_OBJECT (check), "palette", (gpointer)"light");
|
||||
if (g_strcmp0 ("light", self->palette) == 0)
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (check), TRUE);
|
||||
g_signal_connect (check, "toggled", G_CALLBACK (palette_changed), self);
|
||||
gtk_check_button_set_group (GTK_CHECK_BUTTON (check), self->default_check);
|
||||
gtk_box_append (GTK_BOX (box), check);
|
||||
|
||||
check = gtk_check_button_new_with_label ("Dark");
|
||||
g_object_set_data (G_OBJECT (check), "palette", (gpointer)"dark");
|
||||
if (g_strcmp0 ("dark", self->palette) == 0)
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (check), TRUE);
|
||||
g_signal_connect (check, "toggled", G_CALLBACK (palette_changed), self);
|
||||
gtk_check_button_set_group (GTK_CHECK_BUTTON (check), self->default_check);
|
||||
gtk_box_append (GTK_BOX (box), check);
|
||||
|
||||
for (int i = 0; i < hb_ot_color_palette_get_count (hb_face); i++)
|
||||
{
|
||||
char *id = g_strdup_printf ("palette%d", i);
|
||||
char *label = g_strdup_printf ("Palette %d", i);
|
||||
GtkWidget *palette;
|
||||
|
||||
check = gtk_check_button_new_with_label (label);
|
||||
g_object_set_data_full (G_OBJECT (check), "palette", id, g_free);
|
||||
if (g_strcmp0 (id, self->palette) == 0)
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (check), TRUE);
|
||||
g_signal_connect (check, "toggled", G_CALLBACK (palette_changed), self);
|
||||
gtk_check_button_set_group (GTK_CHECK_BUTTON (check), self->default_check);
|
||||
gtk_grid_attach (self->grid, check, 0, i, 1, 1);
|
||||
|
||||
n_colors = hb_ot_color_palette_get_colors (hb_face, i, 0, NULL, NULL);
|
||||
colors = g_new (hb_color_t, n_colors);
|
||||
n_colors = hb_ot_color_palette_get_colors (hb_face, i, 0, &n_colors, colors);
|
||||
|
||||
palette = gtk_grid_new ();
|
||||
gtk_widget_set_valign (palette, GTK_ALIGN_CENTER);
|
||||
gtk_grid_attach (self->grid, palette, 1, i, 1, 1);
|
||||
|
||||
/* HACK - defeat first-child/last-child theming */
|
||||
gtk_grid_attach (GTK_GRID (palette), gtk_picture_new (), -1, 0, 1, 1);
|
||||
|
||||
for (int k = 0; k < n_colors; k++)
|
||||
{
|
||||
GtkWidget *swatch;
|
||||
swatch = g_object_new (g_type_from_name ("GtkColorSwatch"),
|
||||
"rgba", &(GdkRGBA){ hb_color_get_red (colors[k])/255.,
|
||||
hb_color_get_green (colors[k])/255.,
|
||||
hb_color_get_blue (colors[k])/255.,
|
||||
hb_color_get_alpha (colors[k])/255.},
|
||||
"selectable", FALSE,
|
||||
"has-menu", FALSE,
|
||||
"can-drag", FALSE,
|
||||
"width-request", 16,
|
||||
"height-request", 16,
|
||||
NULL);
|
||||
gtk_grid_attach (GTK_GRID (palette), swatch, k % 6, k / 6, 1, 1);
|
||||
}
|
||||
|
||||
/* HACK - defeat first-child/last-child theming */
|
||||
gtk_grid_attach (GTK_GRID (palette), gtk_picture_new (), 6, 0, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
reset (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
FontColors *self)
|
||||
{
|
||||
g_free (self->palette);
|
||||
self->palette = g_strdup (PANGO2_COLOR_PALETTE_DEFAULT);
|
||||
if (self->has_colors)
|
||||
gtk_check_button_set_active (self->default_check, TRUE);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PALETTE]);
|
||||
g_simple_action_set_enabled (self->reset_action, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
font_colors_init (FontColors *self)
|
||||
{
|
||||
self->font_map = g_object_ref (pango2_font_map_get_default ());
|
||||
|
||||
self->palette = g_strdup (PANGO2_COLOR_PALETTE_DEFAULT);
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
self->reset_action = g_simple_action_new ("reset", NULL);
|
||||
g_simple_action_set_enabled (self->reset_action, FALSE);
|
||||
g_signal_connect (self->reset_action, "activate", G_CALLBACK (reset), self);
|
||||
}
|
||||
|
||||
static void
|
||||
font_colors_dispose (GObject *object)
|
||||
{
|
||||
gtk_widget_clear_template (GTK_WIDGET (object), FONT_COLORS_TYPE);
|
||||
|
||||
G_OBJECT_CLASS (font_colors_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
font_colors_finalize (GObject *object)
|
||||
{
|
||||
FontColors *self = FONT_COLORS (object);
|
||||
|
||||
g_clear_pointer (&self->font_desc, pango2_font_description_free);
|
||||
g_free (self->palette);
|
||||
g_clear_object (&self->font_map);
|
||||
|
||||
G_OBJECT_CLASS (font_colors_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
font_colors_set_property (GObject *object,
|
||||
unsigned int prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
FontColors *self = FONT_COLORS (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FONT_MAP:
|
||||
g_set_object (&self->font_map, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_FONT_DESC:
|
||||
pango2_font_description_free (self->font_desc);
|
||||
self->font_desc = pango2_font_description_copy (g_value_get_boxed (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
|
||||
update_colors (self);
|
||||
}
|
||||
|
||||
static void
|
||||
font_colors_get_property (GObject *object,
|
||||
unsigned int prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
FontColors *self = FONT_COLORS (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PALETTE:
|
||||
g_value_set_string (value, self->palette);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
font_colors_class_init (FontColorsClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->dispose = font_colors_dispose;
|
||||
object_class->finalize = font_colors_finalize;
|
||||
object_class->get_property = font_colors_get_property;
|
||||
object_class->set_property = font_colors_set_property;
|
||||
|
||||
properties[PROP_FONT_MAP] =
|
||||
g_param_spec_object ("font-map", "", "",
|
||||
PANGO2_TYPE_FONT_MAP,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_FONT_DESC] =
|
||||
g_param_spec_boxed ("font-desc", "", "",
|
||||
PANGO2_TYPE_FONT_DESCRIPTION,
|
||||
G_PARAM_WRITABLE);
|
||||
|
||||
properties[PROP_PALETTE] =
|
||||
g_param_spec_string ("palette", "", "",
|
||||
PANGO2_COLOR_PALETTE_DEFAULT,
|
||||
G_PARAM_READABLE);
|
||||
|
||||
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/fontexplorer/fontcolors.ui");
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontColors, grid);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontColors, label);
|
||||
|
||||
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "fontcolors");
|
||||
}
|
||||
|
||||
GAction *
|
||||
font_colors_get_reset_action (FontColors *self)
|
||||
{
|
||||
return G_ACTION (self->reset_action);
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define FONT_COLORS_TYPE (font_colors_get_type ())
|
||||
#define FONT_COLORS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_COLORS_TYPE, FontColors))
|
||||
|
||||
|
||||
typedef struct _FontColors FontColors;
|
||||
typedef struct _FontColorsClass FontColorsClass;
|
||||
|
||||
|
||||
GType font_colors_get_type (void);
|
||||
GAction * font_colors_get_reset_action (FontColors *self);
|
||||
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="FontColors" parent="GtkWidget">
|
||||
<property name="layout-manager"><object class="GtkBinLayout"/></property>
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid">
|
||||
<child>
|
||||
<object class="GtkLabel" id="label">
|
||||
<property name="label" translatable="yes">Colors</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="heading"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="row">-2</property>
|
||||
<property name="column">0</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -1,257 +0,0 @@
|
||||
#include "fontcontrols.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <hb-ot.h>
|
||||
|
||||
#include "rangeedit.h"
|
||||
|
||||
enum {
|
||||
PROP_SIZE = 1,
|
||||
PROP_LETTERSPACING,
|
||||
PROP_LINE_HEIGHT,
|
||||
PROP_FOREGROUND,
|
||||
PROP_BACKGROUND,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
struct _FontControls
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
GtkAdjustment *size_adjustment;
|
||||
GtkAdjustment *letterspacing_adjustment;
|
||||
GtkAdjustment *line_height_adjustment;
|
||||
GtkColorButton *foreground;
|
||||
GtkColorButton *background;
|
||||
|
||||
GSimpleAction *reset_action;
|
||||
};
|
||||
|
||||
struct _FontControlsClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FontControls, font_controls, GTK_TYPE_WIDGET);
|
||||
|
||||
static void
|
||||
size_changed (GtkAdjustment *adjustment,
|
||||
FontControls *self)
|
||||
{
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SIZE]);
|
||||
g_simple_action_set_enabled (self->reset_action, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
letterspacing_changed (GtkAdjustment *adjustment,
|
||||
FontControls *self)
|
||||
{
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_LETTERSPACING]);
|
||||
g_simple_action_set_enabled (self->reset_action, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
line_height_changed (GtkAdjustment *adjustment,
|
||||
FontControls *self)
|
||||
{
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_LINE_HEIGHT]);
|
||||
g_simple_action_set_enabled (self->reset_action, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
color_set (GtkColorButton *button,
|
||||
GParamSpec *pspec,
|
||||
FontControls *self)
|
||||
{
|
||||
if (button == self->foreground)
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FOREGROUND]);
|
||||
else
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_BACKGROUND]);
|
||||
g_simple_action_set_enabled (self->reset_action, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
swap_colors (GtkButton *button,
|
||||
FontControls *self)
|
||||
{
|
||||
GdkRGBA fg;
|
||||
GdkRGBA bg;
|
||||
|
||||
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (self->foreground), &fg);
|
||||
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (self->background), &bg);
|
||||
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (self->foreground), &bg);
|
||||
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (self->background), &fg);
|
||||
}
|
||||
|
||||
static void
|
||||
reset (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
FontControls *self)
|
||||
{
|
||||
gtk_adjustment_set_value (self->size_adjustment, 12.);
|
||||
gtk_adjustment_set_value (self->letterspacing_adjustment, 0.);
|
||||
gtk_adjustment_set_value (self->line_height_adjustment, 1.);
|
||||
|
||||
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (self->foreground), &(GdkRGBA){0., 0., 0., 1.0 });
|
||||
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (self->background), &(GdkRGBA){1., 1., 1., 1.0 });
|
||||
|
||||
g_simple_action_set_enabled (self->reset_action, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
font_controls_init (FontControls *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
self->reset_action = g_simple_action_new ("reset", NULL);
|
||||
g_simple_action_set_enabled (self->reset_action, FALSE);
|
||||
g_signal_connect (self->reset_action, "activate", G_CALLBACK (reset), self);
|
||||
}
|
||||
|
||||
static void
|
||||
font_controls_dispose (GObject *object)
|
||||
{
|
||||
gtk_widget_clear_template (GTK_WIDGET (object), FONT_CONTROLS_TYPE);
|
||||
|
||||
G_OBJECT_CLASS (font_controls_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
font_controls_finalize (GObject *object)
|
||||
{
|
||||
//FontControls *self = FONT_CONTROLS (object);
|
||||
|
||||
G_OBJECT_CLASS (font_controls_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
font_controls_set_property (GObject *object,
|
||||
unsigned int prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
FontControls *self = FONT_CONTROLS (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SIZE:
|
||||
gtk_adjustment_set_value (self->size_adjustment, g_value_get_float (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
font_controls_get_property (GObject *object,
|
||||
unsigned int prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
FontControls *self = FONT_CONTROLS (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SIZE:
|
||||
g_value_set_float (value, gtk_adjustment_get_value (self->size_adjustment));
|
||||
break;
|
||||
|
||||
case PROP_LETTERSPACING:
|
||||
g_value_set_int (value, (int) gtk_adjustment_get_value (self->letterspacing_adjustment));
|
||||
break;
|
||||
|
||||
case PROP_LINE_HEIGHT:
|
||||
g_value_set_float (value, gtk_adjustment_get_value (self->line_height_adjustment));
|
||||
break;
|
||||
|
||||
case PROP_FOREGROUND:
|
||||
{
|
||||
GdkRGBA rgba;
|
||||
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (self->foreground), &rgba);
|
||||
g_value_set_boxed (value, &rgba);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_BACKGROUND:
|
||||
{
|
||||
GdkRGBA rgba;
|
||||
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (self->background), &rgba);
|
||||
g_value_set_boxed (value, &rgba);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
font_controls_class_init (FontControlsClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
g_type_ensure (RANGE_EDIT_TYPE);
|
||||
|
||||
object_class->dispose = font_controls_dispose;
|
||||
object_class->finalize = font_controls_finalize;
|
||||
object_class->get_property = font_controls_get_property;
|
||||
object_class->set_property = font_controls_set_property;
|
||||
|
||||
properties[PROP_SIZE] =
|
||||
g_param_spec_float ("size", "", "",
|
||||
0., 100., 12.,
|
||||
G_PARAM_READABLE);
|
||||
|
||||
properties[PROP_LETTERSPACING] =
|
||||
g_param_spec_int ("letterspacing", "", "",
|
||||
-G_MAXINT, G_MAXINT, 0,
|
||||
G_PARAM_READABLE);
|
||||
|
||||
properties[PROP_LINE_HEIGHT] =
|
||||
g_param_spec_float ("line-height", "", "",
|
||||
0., 100., 1.,
|
||||
G_PARAM_READABLE);
|
||||
|
||||
properties[PROP_FOREGROUND] =
|
||||
g_param_spec_boxed ("foreground", "", "",
|
||||
GDK_TYPE_RGBA,
|
||||
G_PARAM_READABLE);
|
||||
|
||||
properties[PROP_BACKGROUND] =
|
||||
g_param_spec_boxed ("background", "", "",
|
||||
GDK_TYPE_RGBA,
|
||||
G_PARAM_READABLE);
|
||||
|
||||
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/fontexplorer/fontcontrols.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontControls, size_adjustment);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontControls, letterspacing_adjustment);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontControls, line_height_adjustment);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontControls, foreground);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontControls, background);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), size_changed);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), letterspacing_changed);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), line_height_changed);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), color_set);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), swap_colors);
|
||||
|
||||
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "fontcontrols");
|
||||
}
|
||||
|
||||
FontControls *
|
||||
font_controls_new (void)
|
||||
{
|
||||
return g_object_new (FONT_CONTROLS_TYPE, NULL);
|
||||
}
|
||||
|
||||
GAction *
|
||||
font_controls_get_reset_action (FontControls *self)
|
||||
{
|
||||
return G_ACTION (self->reset_action);
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define FONT_CONTROLS_TYPE (font_controls_get_type ())
|
||||
#define FONT_CONTROLS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_CONTROLS_TYPE, FontControls))
|
||||
|
||||
|
||||
typedef struct _FontControls FontControls;
|
||||
typedef struct _FontControlsClass FontControlsClass;
|
||||
|
||||
|
||||
GType font_controls_get_type (void);
|
||||
FontControls * font_controls_new (void);
|
||||
GAction * font_controls_get_reset_action (FontControls *self);
|
||||
@@ -1,173 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="FontControls" parent="GtkWidget">
|
||||
<property name="layout-manager"><object class="GtkGridLayout"/></property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Size</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="valign">baseline</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="RangeEdit">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="width-request">160</property>
|
||||
<property name="valign">baseline</property>
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment" id="size_adjustment">
|
||||
<property name="lower">7</property>
|
||||
<property name="upper">100</property>
|
||||
<property name="value">14</property>
|
||||
<property name="step_increment">0.5</property>
|
||||
<property name="page_increment">10</property>
|
||||
<signal name="value-changed" handler="size_changed"/>
|
||||
</object>
|
||||
</property>
|
||||
<property name="default-value">12</property>
|
||||
<property name="n-chars">5</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">0</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Letterspacing</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="valign">baseline</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="RangeEdit">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="width-request">160</property>
|
||||
<property name="valign">baseline</property>
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment" id="letterspacing_adjustment">
|
||||
<property name="lower">-1024</property>
|
||||
<property name="upper">8192</property>
|
||||
<property name="value">0</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">512</property>
|
||||
<signal name="value-changed" handler="letterspacing_changed"/>
|
||||
</object>
|
||||
</property>
|
||||
<property name="default-value">0</property>
|
||||
<property name="n-chars">5</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">1</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Line Height</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="valign">baseline</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="RangeEdit">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="width-request">160</property>
|
||||
<property name="valign">baseline</property>
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment" id="line_height_adjustment">
|
||||
<property name="lower">0.75</property>
|
||||
<property name="upper">2.5</property>
|
||||
<property name="value">1.0</property>
|
||||
<property name="step_increment">0.1</property>
|
||||
<property name="page_increment">1</property>
|
||||
<signal name="value-changed" handler="line_height_changed"/>
|
||||
</object>
|
||||
</property>
|
||||
<property name="default-value">1</property>
|
||||
<property name="n-chars">5</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">2</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Foreground</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="valign">baseline</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColorButton" id="foreground">
|
||||
<property name="rgba">black</property>
|
||||
<signal name="notify::rgba" handler="color_set"/>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Background</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="valign">baseline</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">4</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColorButton" id="background">
|
||||
<property name="rgba">white</property>
|
||||
<signal name="notify::rgba" handler="color_set"/>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">4</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">object-flip-vertical-symbolic</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<style>
|
||||
<class name="circular"/>
|
||||
</style>
|
||||
<signal name="clicked" handler="swap_colors"/>
|
||||
<layout>
|
||||
<property name="column">2</property>
|
||||
<property name="row">3</property>
|
||||
<property name="row-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -1,43 +0,0 @@
|
||||
box.sidebar {
|
||||
padding: 20px;
|
||||
border-spacing: 20px;
|
||||
}
|
||||
fontcontrols {
|
||||
border-spacing: 10px;
|
||||
}
|
||||
fontvariations > grid {
|
||||
border-spacing: 10px;
|
||||
}
|
||||
fontcolors > grid {
|
||||
border-spacing: 10px;
|
||||
}
|
||||
samplechooser {
|
||||
border-spacing: 10px;
|
||||
}
|
||||
plainview .content {
|
||||
padding: 20px;
|
||||
}
|
||||
waterfallview .content {
|
||||
padding: 20px;
|
||||
}
|
||||
styleview .content {
|
||||
padding: 20px;
|
||||
}
|
||||
glyphsview .content {
|
||||
padding: 20px;
|
||||
}
|
||||
infoview .content {
|
||||
padding: 20px;
|
||||
border-spacing: 10px;
|
||||
}
|
||||
gridview > child {
|
||||
padding: 0;
|
||||
}
|
||||
glyphview {
|
||||
padding: 0;
|
||||
border: 0.6px solid gray;
|
||||
}
|
||||
.viewcontrols {
|
||||
padding: 20px;
|
||||
border-spacing: 10px;
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/org/gtk/fontexplorer">
|
||||
<file preprocess="xml-stripblanks">fontcolors.ui</file>
|
||||
<file preprocess="xml-stripblanks">fontcontrols.ui</file>
|
||||
<file preprocess="xml-stripblanks">fontexplorerwin.ui</file>
|
||||
<file preprocess="xml-stripblanks">fontfeatures.ui</file>
|
||||
<file preprocess="xml-stripblanks">fontvariations.ui</file>
|
||||
<file preprocess="xml-stripblanks">glyphsview.ui</file>
|
||||
<file preprocess="xml-stripblanks">infoview.ui</file>
|
||||
<file preprocess="xml-stripblanks">plainview.ui</file>
|
||||
<file preprocess="xml-stripblanks">rangeedit.ui</file>
|
||||
<file preprocess="xml-stripblanks">samplechooser.ui</file>
|
||||
<file preprocess="xml-stripblanks">sampleeditor.ui</file>
|
||||
<file preprocess="xml-stripblanks">styleview.ui</file>
|
||||
<file preprocess="xml-stripblanks">waterfallview.ui</file>
|
||||
<file>fontexplorer.css</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
@@ -1,186 +0,0 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "fontexplorerapp.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "fontexplorerwin.h"
|
||||
|
||||
#include "demo_conf.h"
|
||||
|
||||
struct _FontExplorerApp
|
||||
{
|
||||
GtkApplication parent;
|
||||
};
|
||||
|
||||
struct _FontExplorerAppClass
|
||||
{
|
||||
GtkApplicationClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FontExplorerApp, font_explorer_app, GTK_TYPE_APPLICATION);
|
||||
|
||||
static void
|
||||
font_explorer_app_init (FontExplorerApp *app)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
quit_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer app)
|
||||
{
|
||||
g_application_quit (G_APPLICATION (app));
|
||||
}
|
||||
|
||||
static void
|
||||
inspector_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer app)
|
||||
{
|
||||
gtk_window_set_interactive_debugging (TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
about_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkApplication *app = user_data;
|
||||
const char *authors[] = {
|
||||
"The GTK Team",
|
||||
NULL
|
||||
};
|
||||
char *icon_theme;
|
||||
char *version;
|
||||
GString *s;
|
||||
char *os_name;
|
||||
char *os_version;
|
||||
|
||||
g_object_get (gtk_settings_get_default (),
|
||||
"gtk-icon-theme-name", &icon_theme,
|
||||
NULL);
|
||||
|
||||
s = g_string_new ("");
|
||||
|
||||
os_name = g_get_os_info (G_OS_INFO_KEY_NAME);
|
||||
os_version = g_get_os_info (G_OS_INFO_KEY_VERSION_ID);
|
||||
if (os_name && os_version)
|
||||
g_string_append_printf (s, "OS\t%s %s\n\n", os_name, os_version);
|
||||
g_string_append (s, "System libraries\n");
|
||||
g_string_append_printf (s, "\tGLib\t%d.%d.%d\n",
|
||||
glib_major_version,
|
||||
glib_minor_version,
|
||||
glib_micro_version);
|
||||
g_string_append_printf (s, "\tPango2\t%s\n",
|
||||
pango2_version_string ());
|
||||
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
g_string_append_printf (s, "\nIcon theme\n\t%s", icon_theme);
|
||||
version = g_strdup_printf ("%s%s%s\nRunning against GTK %d.%d.%d",
|
||||
PACKAGE_VERSION,
|
||||
g_strcmp0 (PROFILE, "devel") == 0 ? "-" : "",
|
||||
g_strcmp0 (PROFILE, "devel") == 0 ? VCS_TAG : "",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
|
||||
gtk_show_about_dialog (GTK_WINDOW (gtk_application_get_active_window (app)),
|
||||
"program-name", g_strcmp0 (PROFILE, "devel") == 0
|
||||
? "GTK Font Explorer (Development)"
|
||||
: "GTK Font Explorer",
|
||||
"version", version,
|
||||
"copyright", "© 1997—2021 The GTK Team",
|
||||
"license-type", GTK_LICENSE_LGPL_2_1,
|
||||
"website", "http://www.gtk.org",
|
||||
"comments", "Program to explore font features",
|
||||
"authors", authors,
|
||||
"logo-icon-name", "org.gtk.FontExplorer",
|
||||
"title", "About GTK Font Explorer",
|
||||
"system-information", s->str,
|
||||
NULL);
|
||||
|
||||
g_string_free (s, TRUE);
|
||||
g_free (version);
|
||||
g_free (icon_theme);
|
||||
g_free (os_name);
|
||||
g_free (os_version);
|
||||
}
|
||||
|
||||
static GActionEntry app_entries[] =
|
||||
{
|
||||
{ "quit", quit_activated, NULL, NULL, NULL },
|
||||
{ "inspector", inspector_activated, NULL, NULL, NULL },
|
||||
{ "about", about_activated, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
font_explorer_app_startup (GApplication *app)
|
||||
{
|
||||
const char *quit_accels[2] = { "<Ctrl>Q", NULL };
|
||||
GtkCssProvider *provider;
|
||||
|
||||
G_APPLICATION_CLASS (font_explorer_app_parent_class)->startup (app);
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (app),
|
||||
app_entries, G_N_ELEMENTS (app_entries),
|
||||
app);
|
||||
gtk_application_set_accels_for_action (GTK_APPLICATION (app),
|
||||
"app.quit",
|
||||
quit_accels);
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (provider, "/org/gtk/fontexplorer/fontexplorer.css");
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
}
|
||||
|
||||
static void
|
||||
font_explorer_app_activate (GApplication *app)
|
||||
{
|
||||
FontExplorerWindow *win;
|
||||
|
||||
win = font_explorer_window_new (FONT_EXPLORER_APP (app));
|
||||
|
||||
if (g_strcmp0 (PROFILE, "devel") == 0)
|
||||
gtk_widget_add_css_class (GTK_WIDGET (win), "devel");
|
||||
|
||||
gtk_window_present (GTK_WINDOW (win));
|
||||
}
|
||||
|
||||
static void
|
||||
font_explorer_app_open (GApplication *app,
|
||||
GFile **files,
|
||||
int n_files,
|
||||
const char *hint)
|
||||
{
|
||||
FontExplorerWindow *win;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_files; i++)
|
||||
{
|
||||
win = font_explorer_window_new (FONT_EXPLORER_APP (app));
|
||||
font_explorer_window_load (win, files[i]);
|
||||
gtk_window_present (GTK_WINDOW (win));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
font_explorer_app_class_init (FontExplorerAppClass *class)
|
||||
{
|
||||
G_APPLICATION_CLASS (class)->startup = font_explorer_app_startup;
|
||||
G_APPLICATION_CLASS (class)->activate = font_explorer_app_activate;
|
||||
G_APPLICATION_CLASS (class)->open = font_explorer_app_open;
|
||||
}
|
||||
|
||||
FontExplorerApp *
|
||||
font_explorer_app_new (void)
|
||||
{
|
||||
return g_object_new (FONT_EXPLORER_APP_TYPE,
|
||||
"application-id", "org.gtk.FontExplorer",
|
||||
"flags", G_APPLICATION_HANDLES_OPEN,
|
||||
NULL);
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define FONT_EXPLORER_APP_TYPE (font_explorer_app_get_type ())
|
||||
#define FONT_EXPLORER_APP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_EXPLORER_APP_TYPE, FontExplorerApp))
|
||||
|
||||
|
||||
typedef struct _FontExplorerApp FontExplorerApp;
|
||||
typedef struct _FontExplorerAppClass FontExplorerAppClass;
|
||||
|
||||
|
||||
GType font_explorer_app_get_type (void);
|
||||
FontExplorerApp * font_explorer_app_new (void);
|
||||
@@ -1,269 +0,0 @@
|
||||
#include "fontexplorerwin.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fontcolors.h"
|
||||
#include "fontcontrols.h"
|
||||
#include "fontexplorerapp.h"
|
||||
#include "fontfeatures.h"
|
||||
#include "fontvariations.h"
|
||||
#include "glyphsview.h"
|
||||
#include "infoview.h"
|
||||
#include "plainview.h"
|
||||
#include "samplechooser.h"
|
||||
#include "sampleeditor.h"
|
||||
#include "styleview.h"
|
||||
#include "waterfallview.h"
|
||||
|
||||
struct _FontExplorerWindow
|
||||
{
|
||||
GtkApplicationWindow parent;
|
||||
|
||||
Pango2FontMap *font_map;
|
||||
|
||||
GtkFontButton *fontbutton;
|
||||
GtkLabel *path;
|
||||
FontControls *controls;
|
||||
FontFeatures *features;
|
||||
FontVariations *variations;
|
||||
FontColors *colors;
|
||||
GtkStack *stack;
|
||||
GtkToggleButton *plain_toggle;
|
||||
GtkToggleButton *waterfall_toggle;
|
||||
GtkToggleButton *style_toggle;
|
||||
GtkToggleButton *glyphs_toggle;
|
||||
GtkToggleButton *info_toggle;
|
||||
GtkToggleButton *edit_toggle;
|
||||
};
|
||||
|
||||
struct _FontExplorerWindowClass
|
||||
{
|
||||
GtkApplicationWindowClass parent_class;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_FONT_MAP = 1,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
G_DEFINE_TYPE(FontExplorerWindow, font_explorer_window, GTK_TYPE_APPLICATION_WINDOW);
|
||||
|
||||
static void
|
||||
reset (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
FontExplorerWindow *self)
|
||||
{
|
||||
g_action_activate (font_controls_get_reset_action (self->controls), NULL);
|
||||
g_action_activate (font_features_get_reset_action (self->features), NULL);
|
||||
g_action_activate (font_variations_get_reset_action (self->variations), NULL);
|
||||
g_action_activate (font_colors_get_reset_action (self->colors), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
update_reset (GSimpleAction *action,
|
||||
GParamSpec *pspec,
|
||||
FontExplorerWindow *self)
|
||||
{
|
||||
gboolean enabled;
|
||||
GAction *reset_action;
|
||||
|
||||
enabled = g_action_get_enabled (font_controls_get_reset_action (self->controls)) ||
|
||||
g_action_get_enabled (font_features_get_reset_action (self->features)) ||
|
||||
g_action_get_enabled (font_variations_get_reset_action (self->variations)) ||
|
||||
g_action_get_enabled (font_colors_get_reset_action (self->colors));
|
||||
|
||||
reset_action = g_action_map_lookup_action (G_ACTION_MAP (self), "reset");
|
||||
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (reset_action), enabled);
|
||||
}
|
||||
|
||||
static void
|
||||
font_explorer_window_init (FontExplorerWindow *self)
|
||||
{
|
||||
GSimpleAction *reset_action;
|
||||
|
||||
self->font_map = g_object_ref (pango2_font_map_get_default ());
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
reset_action = g_simple_action_new ("reset", NULL);
|
||||
g_signal_connect (reset_action, "activate", G_CALLBACK (reset), self);
|
||||
g_signal_connect (font_controls_get_reset_action (self->controls),
|
||||
"notify::enabled", G_CALLBACK (update_reset), self);
|
||||
g_signal_connect (font_variations_get_reset_action (self->variations),
|
||||
"notify::enabled", G_CALLBACK (update_reset), self);
|
||||
g_signal_connect (font_colors_get_reset_action (self->colors),
|
||||
"notify::enabled", G_CALLBACK (update_reset), self);
|
||||
g_signal_connect (font_features_get_reset_action (self->features),
|
||||
"notify::enabled", G_CALLBACK (update_reset), self);
|
||||
|
||||
g_action_map_add_action (G_ACTION_MAP (self), G_ACTION (reset_action));
|
||||
update_reset (NULL, NULL, self);
|
||||
}
|
||||
|
||||
static void
|
||||
update_view (GtkToggleButton *button,
|
||||
FontExplorerWindow *self)
|
||||
{
|
||||
if (gtk_toggle_button_get_active (self->edit_toggle))
|
||||
gtk_stack_set_visible_child_name (self->stack, "edit");
|
||||
else if (gtk_toggle_button_get_active (self->plain_toggle))
|
||||
gtk_stack_set_visible_child_name (self->stack, "plain");
|
||||
else if (gtk_toggle_button_get_active (self->waterfall_toggle))
|
||||
gtk_stack_set_visible_child_name (self->stack, "waterfall");
|
||||
else if (gtk_toggle_button_get_active (self->style_toggle))
|
||||
gtk_stack_set_visible_child_name (self->stack, "style");
|
||||
else if (gtk_toggle_button_get_active (self->glyphs_toggle))
|
||||
gtk_stack_set_visible_child_name (self->stack, "glyphs");
|
||||
else if (gtk_toggle_button_get_active (self->info_toggle))
|
||||
gtk_stack_set_visible_child_name (self->stack, "info");
|
||||
}
|
||||
|
||||
static void
|
||||
font_explorer_window_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
FontExplorerWindow *self = FONT_EXPLORER_WINDOW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FONT_MAP:
|
||||
g_set_object (&self->font_map, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
font_explorer_window_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
FontExplorerWindow *self = FONT_EXPLORER_WINDOW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FONT_MAP:
|
||||
g_value_set_object (value, self->font_map);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
font_explorer_window_dispose (GObject *object)
|
||||
{
|
||||
gtk_widget_clear_template (GTK_WIDGET (object), FONT_EXPLORER_WINDOW_TYPE);
|
||||
|
||||
G_OBJECT_CLASS (font_explorer_window_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
font_explorer_window_finalize (GObject *object)
|
||||
{
|
||||
FontExplorerWindow *self = FONT_EXPLORER_WINDOW (object);
|
||||
|
||||
g_clear_object (&self->font_map);
|
||||
|
||||
G_OBJECT_CLASS (font_explorer_window_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
font_explorer_window_class_init (FontExplorerWindowClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
g_type_ensure (FONT_COLORS_TYPE);
|
||||
g_type_ensure (FONT_CONTROLS_TYPE);
|
||||
g_type_ensure (FONT_FEATURES_TYPE);
|
||||
g_type_ensure (FONT_VARIATIONS_TYPE);
|
||||
g_type_ensure (GLYPHS_VIEW_TYPE);
|
||||
g_type_ensure (INFO_VIEW_TYPE);
|
||||
g_type_ensure (PLAIN_VIEW_TYPE);
|
||||
g_type_ensure (SAMPLE_CHOOSER_TYPE);
|
||||
g_type_ensure (SAMPLE_EDITOR_TYPE);
|
||||
g_type_ensure (STYLE_VIEW_TYPE);
|
||||
g_type_ensure (WATERFALL_VIEW_TYPE);
|
||||
|
||||
object_class->set_property = font_explorer_window_set_property;
|
||||
object_class->get_property = font_explorer_window_get_property;
|
||||
object_class->dispose = font_explorer_window_dispose;
|
||||
object_class->finalize = font_explorer_window_finalize;
|
||||
|
||||
properties[PROP_FONT_MAP] =
|
||||
g_param_spec_object ("font-map", "", "",
|
||||
PANGO2_TYPE_FONT_MAP,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/fontexplorer/fontexplorerwin.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, fontbutton);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, path);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, controls);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, variations);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, colors);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, features);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, stack);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, plain_toggle);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, waterfall_toggle);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, style_toggle);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, glyphs_toggle);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, info_toggle);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, edit_toggle);
|
||||
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), update_view);
|
||||
}
|
||||
|
||||
FontExplorerWindow *
|
||||
font_explorer_window_new (FontExplorerApp *app)
|
||||
{
|
||||
return g_object_new (FONT_EXPLORER_WINDOW_TYPE, "application", app, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
font_explorer_window_load (FontExplorerWindow *self,
|
||||
GFile *file)
|
||||
{
|
||||
const char *path;
|
||||
Pango2FontMap *map;
|
||||
Pango2HbFace *face;
|
||||
Pango2FontDescription *desc;
|
||||
char *basename;
|
||||
|
||||
path = g_file_peek_path (file);
|
||||
basename = g_path_get_basename (path);
|
||||
|
||||
face = pango2_hb_face_new_from_file (path, 0, -2, NULL, NULL);
|
||||
desc = pango2_font_face_describe (PANGO2_FONT_FACE (face));
|
||||
|
||||
map = pango2_font_map_new ();
|
||||
pango2_font_map_add_face (map, PANGO2_FONT_FACE (face));
|
||||
pango2_font_map_set_fallback (map, pango2_font_map_get_default ());
|
||||
|
||||
g_set_object (&self->font_map, map);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FONT_MAP]);
|
||||
|
||||
g_object_unref (map);
|
||||
|
||||
gtk_font_chooser_set_font_desc (GTK_FONT_CHOOSER (self->fontbutton), desc);
|
||||
|
||||
gtk_widget_hide (GTK_WIDGET (self->fontbutton));
|
||||
gtk_widget_show (GTK_WIDGET (self->path));
|
||||
gtk_label_set_label (self->path, basename);
|
||||
|
||||
pango2_font_description_free (desc);
|
||||
g_free (basename);
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "fontexplorerapp.h"
|
||||
|
||||
|
||||
#define FONT_EXPLORER_WINDOW_TYPE (font_explorer_window_get_type ())
|
||||
#define FONT_EXPLORER_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_EXPLORER_WINDOW_TYPE, FontExplorerWindow))
|
||||
|
||||
|
||||
typedef struct _FontExplorerWindow FontExplorerWindow;
|
||||
typedef struct _FontExplorerWindowClass FontExplorerWindowClass;
|
||||
|
||||
|
||||
GType font_explorer_window_get_type (void);
|
||||
FontExplorerWindow * font_explorer_window_new (FontExplorerApp *app);
|
||||
void font_explorer_window_load (FontExplorerWindow *self,
|
||||
GFile *file);
|
||||
@@ -1,252 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<menu id="gear_menu">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Inspector</attribute>
|
||||
<attribute name="action">app.inspector</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_About GTK Font Explorer</attribute>
|
||||
<attribute name="action">app.about</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
<template class="FontExplorerWindow" parent="GtkApplicationWindow">
|
||||
<property name="title" translatable="yes">Font Explorer</property>
|
||||
<property name="default-width">1024</property>
|
||||
<property name="default-height">768</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<child>
|
||||
<object class="GtkButton" id="reset">
|
||||
<property name="receives-default">1</property>
|
||||
<property name="tooltip-text">Reset</property>
|
||||
<property name="icon-name">view-refresh-symbolic</property>
|
||||
<property name="action-name">win.reset</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="title">
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">horizontal</property>
|
||||
<style>
|
||||
<class name="linked"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="plain_toggle">
|
||||
<property name="label">Plain</property>
|
||||
<property name="active">1</property>
|
||||
<signal name="toggled" handler="update_view"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="waterfall_toggle">
|
||||
<property name="label">Waterfall</property>
|
||||
<property name="group">plain_toggle</property>
|
||||
<signal name="toggled" handler="update_view"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="style_toggle">
|
||||
<property name="label">Styles</property>
|
||||
<property name="group">plain_toggle</property>
|
||||
<property name="sensitive" bind-source="styleview" bind-property="has-styles" bind-flags="sync-create"/>
|
||||
<signal name="toggled" handler="update_view"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="glyphs_toggle">
|
||||
<property name="label">Glyphs</property>
|
||||
<property name="group">plain_toggle</property>
|
||||
<signal name="toggled" handler="update_view"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="info_toggle">
|
||||
<property name="label">Info</property>
|
||||
<property name="group">plain_toggle</property>
|
||||
<signal name="toggled" handler="update_view"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkMenuButton" id="gear_menu_button">
|
||||
<property name="focus-on-click">0</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="menu-model">gear_menu</property>
|
||||
<property name="icon-name">open-menu-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkToggleButton" id="edit_toggle">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="icon-name">document-edit-symbolic</property>
|
||||
<property name="tooltip-text" translatable="yes">Edit the sample</property>
|
||||
<signal name="toggled" handler="update_view"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<style>
|
||||
<class name="sidebar"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkFontButton" id="fontbutton">
|
||||
<property name="level">family|style</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="path">
|
||||
<property name="visible">0</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="FontControls" id="controls">
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="SampleChooser" id="samplechooser"/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="FontVariations" id="variations">
|
||||
<property name="font-map" bind-source="FontExplorerWindow" bind-flags="sync-create"/>
|
||||
<property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="FontFeatures" id="features">
|
||||
<property name="font-map" bind-source="FontExplorerWindow" bind-flags="sync-create"/>
|
||||
<property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
|
||||
<property name="language" bind-source="fontbutton" bind-flags="sync-create"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="FontColors" id="colors">
|
||||
<property name="font-map" bind-source="FontExplorerWindow" bind-flags="sync-create"/>
|
||||
<property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStack" id="stack">
|
||||
<property name="hexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">plain</property>
|
||||
<property name="child">
|
||||
<object class="PlainView">
|
||||
<property name="font-map" bind-source="FontExplorerWindow" bind-flags="sync-create"/>
|
||||
<property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
|
||||
<property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
|
||||
<property name="size" bind-source="controls" bind-flags="sync-create"/>
|
||||
<property name="letterspacing" bind-source="controls" bind-flags="sync-create"/>
|
||||
<property name="line-height" bind-source="controls" bind-flags="sync-create"/>
|
||||
<property name="foreground" bind-source="controls" bind-flags="sync-create"/>
|
||||
<property name="background" bind-source="controls" bind-flags="sync-create"/>
|
||||
<property name="sample-text" bind-source="sampleeditor" bind-flags="sync-create"/>
|
||||
<property name="features" bind-source="features" bind-flags="sync-create"/>
|
||||
<property name="variations" bind-source="variations" bind-flags="sync-create"/>
|
||||
<property name="palette" bind-source="colors" bind-flags="sync-create"/>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">waterfall</property>
|
||||
<property name="child">
|
||||
<object class="WaterfallView">
|
||||
<property name="font-map" bind-source="FontExplorerWindow" bind-flags="sync-create"/>
|
||||
<property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
|
||||
<property name="size" bind-source="controls" bind-flags="sync-create"/>
|
||||
<property name="letterspacing" bind-source="controls" bind-flags="sync-create"/>
|
||||
<property name="line-height" bind-source="controls" bind-flags="sync-create"/>
|
||||
<property name="foreground" bind-source="controls" bind-flags="sync-create"/>
|
||||
<property name="background" bind-source="controls" bind-flags="sync-create"/>
|
||||
<property name="sample-text" bind-source="sampleeditor" bind-flags="sync-create"/>
|
||||
<property name="features" bind-source="features" bind-flags="sync-create"/>
|
||||
<property name="variations" bind-source="variations" bind-flags="sync-create"/>
|
||||
<property name="palette" bind-source="colors" bind-flags="sync-create"/>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">style</property>
|
||||
<property name="child">
|
||||
<object class="StyleView" id="styleview">
|
||||
<property name="font-map" bind-source="FontExplorerWindow" bind-flags="sync-create"/>
|
||||
<property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
|
||||
<property name="size" bind-source="controls" bind-flags="sync-create"/>
|
||||
<property name="letterspacing" bind-source="controls" bind-flags="sync-create"/>
|
||||
<property name="line-height" bind-source="controls" bind-flags="sync-create"/>
|
||||
<property name="foreground" bind-source="controls" bind-flags="sync-create"/>
|
||||
<property name="background" bind-source="controls" bind-flags="sync-create"/>
|
||||
<property name="sample-text" bind-source="sampleeditor" bind-flags="sync-create"/>
|
||||
<property name="features" bind-source="features" bind-flags="sync-create"/>
|
||||
<property name="variations" bind-source="variations" bind-flags="sync-create"/>
|
||||
<property name="palette" bind-source="colors" bind-flags="sync-create"/>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">glyphs</property>
|
||||
<property name="child">
|
||||
<object class="GlyphsView">
|
||||
<property name="font-map" bind-source="FontExplorerWindow" bind-flags="sync-create"/>
|
||||
<property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
|
||||
<property name="variations" bind-source="variations" bind-flags="sync-create"/>
|
||||
<property name="palette" bind-source="colors" bind-flags="sync-create"/>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">info</property>
|
||||
<property name="child">
|
||||
<object class="InfoView">
|
||||
<property name="font-map" bind-source="FontExplorerWindow" bind-flags="sync-create"/>
|
||||
<property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
|
||||
<property name="size" bind-source="controls" bind-flags="sync-create"/>
|
||||
<property name="variations" bind-source="variations" bind-flags="sync-create"/>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">edit</property>
|
||||
<property name="child">
|
||||
<object class="SampleEditor" id="sampleeditor">
|
||||
<property name="sample-text" bind-source="samplechooser" bind-flags="sync-create"/>
|
||||
<property name="editing" bind-source="edit_toggle" bind-property="active" bind-flags="sync-create"/>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -1,744 +0,0 @@
|
||||
#include "fontfeatures.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <hb-ot.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "open-type-layout.h"
|
||||
#include "language-names.h"
|
||||
|
||||
enum {
|
||||
PROP_FONT_MAP = 1,
|
||||
PROP_FONT_DESC,
|
||||
PROP_LANGUAGE,
|
||||
PROP_FEATURES,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
typedef struct {
|
||||
unsigned int tag;
|
||||
const char *name;
|
||||
GtkWidget *feat;
|
||||
} FeatureItem;
|
||||
|
||||
struct _FontFeatures
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
GtkGrid *label;
|
||||
GtkGrid *grid;
|
||||
Pango2FontDescription *font_desc;
|
||||
GSimpleAction *reset_action;
|
||||
Pango2Language *lang;
|
||||
GList *feature_items;
|
||||
|
||||
Pango2FontMap *font_map;
|
||||
};
|
||||
|
||||
struct _FontFeaturesClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FontFeatures, font_features, GTK_TYPE_WIDGET);
|
||||
|
||||
static Pango2Font *
|
||||
get_font (FontFeatures *self)
|
||||
{
|
||||
Pango2Context *context;
|
||||
Pango2Font *font;
|
||||
|
||||
context = pango2_context_new_with_font_map (self->font_map);
|
||||
font = pango2_context_load_font (context, self->font_desc);
|
||||
g_object_unref (context);
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_ssNN (const char *buf)
|
||||
{
|
||||
return g_str_has_prefix (buf, "ss") && g_ascii_isdigit (buf[2]) && g_ascii_isdigit (buf[3]);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_cvNN (const char *buf)
|
||||
{
|
||||
return g_str_has_prefix (buf, "cv") && g_ascii_isdigit (buf[2]) && g_ascii_isdigit (buf[3]);
|
||||
}
|
||||
|
||||
static char *
|
||||
get_feature_display_name (unsigned int tag)
|
||||
{
|
||||
int i;
|
||||
static char buf[5] = { 0, };
|
||||
|
||||
if (tag == HB_TAG ('x', 'x', 'x', 'x'))
|
||||
return g_strdup (_("Default"));
|
||||
|
||||
hb_tag_to_string (tag, buf);
|
||||
if (is_ssNN (buf))
|
||||
{
|
||||
int num = (buf[2] - '0') * 10 + (buf[3] - '0');
|
||||
return g_strdup_printf (g_dpgettext2 (NULL, "OpenType layout", "Stylistic Set %d"), num);
|
||||
}
|
||||
else if (is_cvNN (buf))
|
||||
{
|
||||
int num = (buf[2] - '0') * 10 + (buf[3] - '0');
|
||||
return g_strdup_printf (g_dpgettext2 (NULL, "OpenType layout", "Character Variant %d"), num);
|
||||
}
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (open_type_layout_features); i++)
|
||||
{
|
||||
if (tag == open_type_layout_features[i].tag)
|
||||
return g_strdup (g_dpgettext2 (NULL, "OpenType layout", open_type_layout_features[i].name));
|
||||
}
|
||||
|
||||
g_warning ("unknown OpenType layout feature tag: %s", buf);
|
||||
|
||||
return g_strdup (buf);
|
||||
}
|
||||
|
||||
static void
|
||||
update_feature_label (FontFeatures *self,
|
||||
FeatureItem *item,
|
||||
hb_font_t *hb_font,
|
||||
hb_tag_t script_tag,
|
||||
hb_tag_t lang_tag)
|
||||
{
|
||||
hb_face_t *hb_face;
|
||||
unsigned int script_index, lang_index, feature_index;
|
||||
hb_ot_name_id_t id;
|
||||
unsigned int len;
|
||||
char *label;
|
||||
char name[5] = { 0, };
|
||||
|
||||
hb_face = hb_font_get_face (hb_font);
|
||||
|
||||
hb_tag_to_string (item->tag, name);
|
||||
if (!is_ssNN (name) && !is_cvNN (name))
|
||||
return;
|
||||
|
||||
hb_ot_layout_table_find_script (hb_face, HB_OT_TAG_GSUB, script_tag, &script_index);
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
hb_ot_layout_script_find_language (hb_face, HB_OT_TAG_GSUB, script_index, lang_tag, &lang_index);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
if (hb_ot_layout_language_find_feature (hb_face, HB_OT_TAG_GSUB, script_index, lang_index, item->tag, &feature_index) &&
|
||||
hb_ot_layout_feature_get_name_ids (hb_face, HB_OT_TAG_GSUB, feature_index, &id, NULL, NULL, NULL, NULL))
|
||||
{
|
||||
len = hb_ot_name_get_utf8 (hb_face, id, HB_LANGUAGE_INVALID, NULL, NULL);
|
||||
len++;
|
||||
label = g_new (char, len);
|
||||
hb_ot_name_get_utf8 (hb_face, id, HB_LANGUAGE_INVALID, &len, label);
|
||||
|
||||
gtk_check_button_set_label (GTK_CHECK_BUTTON (item->feat), label);
|
||||
|
||||
g_free (label);
|
||||
}
|
||||
else
|
||||
{
|
||||
label = get_feature_display_name (item->tag);
|
||||
gtk_check_button_set_label (GTK_CHECK_BUTTON (item->feat), label);
|
||||
g_free (label);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_inconsistent (GtkCheckButton *button,
|
||||
gboolean inconsistent)
|
||||
{
|
||||
gtk_check_button_set_inconsistent (GTK_CHECK_BUTTON (button), inconsistent);
|
||||
gtk_widget_set_opacity (gtk_widget_get_first_child (GTK_WIDGET (button)), inconsistent ? 0.0 : 1.0);
|
||||
}
|
||||
|
||||
static void
|
||||
find_language_and_script (FontFeatures *self,
|
||||
hb_face_t *hb_face,
|
||||
hb_tag_t *lang_tag,
|
||||
hb_tag_t *script_tag)
|
||||
{
|
||||
int i, j, k;
|
||||
hb_tag_t scripts[80];
|
||||
unsigned int n_scripts;
|
||||
unsigned int count;
|
||||
hb_tag_t table[2] = { HB_OT_TAG_GSUB, HB_OT_TAG_GPOS };
|
||||
hb_language_t lang;
|
||||
const char *langname, *p;
|
||||
|
||||
langname = pango2_language_to_string (self->lang);
|
||||
|
||||
p = strchr (langname, '-');
|
||||
lang = hb_language_from_string (langname, p ? p - langname : -1);
|
||||
|
||||
n_scripts = 0;
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
count = G_N_ELEMENTS (scripts);
|
||||
hb_ot_layout_table_get_script_tags (hb_face, table[i], n_scripts, &count, scripts);
|
||||
n_scripts += count;
|
||||
}
|
||||
|
||||
for (j = 0; j < n_scripts; j++)
|
||||
{
|
||||
hb_tag_t languages[80];
|
||||
unsigned int n_languages;
|
||||
|
||||
n_languages = 0;
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
count = G_N_ELEMENTS (languages);
|
||||
hb_ot_layout_script_get_language_tags (hb_face, table[i], j, n_languages, &count, languages);
|
||||
n_languages += count;
|
||||
}
|
||||
|
||||
for (k = 0; k < n_languages; k++)
|
||||
{
|
||||
if (lang == hb_ot_tag_to_language (languages[k]))
|
||||
{
|
||||
*script_tag = scripts[j];
|
||||
*lang_tag = languages[k];
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*lang_tag = HB_OT_TAG_DEFAULT_LANGUAGE;
|
||||
*script_tag = HB_OT_TAG_DEFAULT_SCRIPT;
|
||||
}
|
||||
|
||||
static void
|
||||
hide_feature_maybe (FeatureItem *item,
|
||||
gboolean has_feature)
|
||||
{
|
||||
gtk_widget_set_visible (item->feat, has_feature);
|
||||
if (has_feature)
|
||||
gtk_widget_set_visible (gtk_widget_get_parent (item->feat), TRUE);
|
||||
}
|
||||
|
||||
/* Make features insensitive if the font/langsys does not have them,
|
||||
* and reset all others to their initial value
|
||||
*/
|
||||
static void
|
||||
update_features (FontFeatures *self)
|
||||
{
|
||||
guint script_index, lang_index;
|
||||
hb_tag_t lang_tag;
|
||||
hb_tag_t script_tag;
|
||||
Pango2Font *font;
|
||||
hb_font_t *hb_font;
|
||||
hb_face_t *hb_face;
|
||||
|
||||
font = get_font (self);
|
||||
hb_font = pango2_font_get_hb_font (font);
|
||||
hb_face = hb_font_get_face (hb_font);
|
||||
|
||||
{
|
||||
hb_tag_t table[2] = { HB_OT_TAG_GSUB, HB_OT_TAG_GPOS };
|
||||
hb_tag_t features[256];
|
||||
unsigned int count;
|
||||
unsigned int n_features = 0;
|
||||
|
||||
find_language_and_script (self, hb_face, &lang_tag, &script_tag);
|
||||
|
||||
/* Collect all features */
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
hb_ot_layout_table_find_script (hb_face,
|
||||
table[i],
|
||||
script_tag,
|
||||
&script_index);
|
||||
hb_ot_layout_script_select_language (hb_face,
|
||||
table[i],
|
||||
script_index,
|
||||
1,
|
||||
&lang_tag,
|
||||
&lang_index);
|
||||
|
||||
count = G_N_ELEMENTS (features);
|
||||
hb_ot_layout_language_get_feature_tags (hb_face,
|
||||
table[i],
|
||||
script_index,
|
||||
lang_index,
|
||||
n_features,
|
||||
&count,
|
||||
features);
|
||||
n_features += count;
|
||||
}
|
||||
|
||||
/* Update all the features */
|
||||
for (GList *l = self->feature_items; l; l = l->next)
|
||||
{
|
||||
FeatureItem *item = l->data;
|
||||
gboolean has_feature = FALSE;
|
||||
|
||||
for (int j = 0; j < n_features; j++)
|
||||
{
|
||||
if (item->tag == features[j])
|
||||
{
|
||||
has_feature = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
update_feature_label (self, item, hb_font, script_tag, lang_tag);
|
||||
|
||||
hide_feature_maybe (item, has_feature);
|
||||
|
||||
if (GTK_IS_CHECK_BUTTON (item->feat))
|
||||
{
|
||||
GtkWidget *def = GTK_WIDGET (g_object_get_data (G_OBJECT (item->feat), "default"));
|
||||
if (def)
|
||||
{
|
||||
gtk_widget_show (def);
|
||||
gtk_widget_show (gtk_widget_get_parent (def));
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (def), TRUE);
|
||||
}
|
||||
else
|
||||
set_inconsistent (GTK_CHECK_BUTTON (item->feat), TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Hide empty groups */
|
||||
for (GList *l = self->feature_items; l; l = l->next)
|
||||
{
|
||||
FeatureItem *item = l->data;
|
||||
GtkWidget *box;
|
||||
|
||||
box = gtk_widget_get_parent (item->feat);
|
||||
if (gtk_widget_get_visible (box))
|
||||
{
|
||||
GtkWidget *c;
|
||||
int count;
|
||||
|
||||
count = 0;
|
||||
for (c = gtk_widget_get_first_child (box); c; c = gtk_widget_get_next_sibling (c))
|
||||
{
|
||||
if (gtk_widget_get_visible (c))
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count == 1)
|
||||
gtk_widget_hide (box);
|
||||
else if (count == 2 &&
|
||||
item->tag == HB_TAG ('x', 'x', 'x', 'x'))
|
||||
gtk_widget_hide (box);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
script_changed (GtkComboBox *combo,
|
||||
FontFeatures *self)
|
||||
{
|
||||
update_features (self);
|
||||
}
|
||||
|
||||
static char *
|
||||
get_features (FontFeatures *self)
|
||||
{
|
||||
GString *s;
|
||||
char buf[128];
|
||||
|
||||
s = g_string_new ("");
|
||||
|
||||
for (GList *l = self->feature_items; l; l = l->next)
|
||||
{
|
||||
FeatureItem *item = l->data;
|
||||
|
||||
if (!gtk_widget_is_sensitive (item->feat))
|
||||
continue;
|
||||
|
||||
if (GTK_IS_CHECK_BUTTON (item->feat) && g_object_get_data (G_OBJECT (item->feat), "default"))
|
||||
{
|
||||
if (gtk_check_button_get_active (GTK_CHECK_BUTTON (item->feat)) &&
|
||||
item->tag != HB_TAG ('x', 'x', 'x', 'x'))
|
||||
{
|
||||
hb_feature_to_string (&(hb_feature_t) { item->tag, 1, 0, -1 }, buf, sizeof (buf));
|
||||
if (s->len > 0)
|
||||
g_string_append_c (s, ',');
|
||||
g_string_append (s, buf);
|
||||
}
|
||||
}
|
||||
else if (GTK_IS_CHECK_BUTTON (item->feat))
|
||||
{
|
||||
guint32 value;
|
||||
|
||||
if (gtk_check_button_get_inconsistent (GTK_CHECK_BUTTON (item->feat)))
|
||||
continue;
|
||||
|
||||
value = gtk_check_button_get_active (GTK_CHECK_BUTTON (item->feat));
|
||||
hb_feature_to_string (&(hb_feature_t) { item->tag, value, 0, -1 }, buf, sizeof (buf));
|
||||
if (s->len > 0)
|
||||
g_string_append_c (s, ',');
|
||||
g_string_append (s, buf);
|
||||
}
|
||||
}
|
||||
|
||||
return g_string_free (s, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
update_display (FontFeatures *self)
|
||||
{
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FEATURES]);
|
||||
g_simple_action_set_enabled (self->reset_action, TRUE);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
make_title_label (const char *title)
|
||||
{
|
||||
GtkWidget *label;
|
||||
|
||||
label = gtk_label_new (title);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
g_object_set (label, "margin-top", 10, "margin-bottom", 10, NULL);
|
||||
gtk_widget_add_css_class (label, "heading");
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
static void
|
||||
feat_toggled_cb (GtkCheckButton *check_button,
|
||||
gpointer data)
|
||||
{
|
||||
set_inconsistent (check_button, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
feat_pressed (GtkGestureClick *gesture,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
GtkWidget *feat)
|
||||
{
|
||||
const guint button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
|
||||
|
||||
if (button == GDK_BUTTON_PRIMARY)
|
||||
{
|
||||
g_signal_handlers_block_by_func (feat, feat_pressed, NULL);
|
||||
|
||||
if (gtk_check_button_get_inconsistent (GTK_CHECK_BUTTON (feat)))
|
||||
{
|
||||
set_inconsistent (GTK_CHECK_BUTTON (feat), FALSE);
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (feat), TRUE);
|
||||
}
|
||||
|
||||
g_signal_handlers_unblock_by_func (feat, feat_pressed, NULL);
|
||||
}
|
||||
else if (button == GDK_BUTTON_SECONDARY)
|
||||
{
|
||||
gboolean inconsistent = gtk_check_button_get_inconsistent (GTK_CHECK_BUTTON (feat));
|
||||
set_inconsistent (GTK_CHECK_BUTTON (feat), !inconsistent);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_check_group (FontFeatures *self,
|
||||
const char *title,
|
||||
const char **tags,
|
||||
unsigned int n_tags,
|
||||
int row)
|
||||
{
|
||||
GtkWidget *group;
|
||||
int i;
|
||||
|
||||
group = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_widget_set_halign (group, GTK_ALIGN_START);
|
||||
|
||||
gtk_box_append (GTK_BOX (group), make_title_label (title));
|
||||
|
||||
for (i = 0; i < n_tags; i++)
|
||||
{
|
||||
unsigned int tag;
|
||||
GtkWidget *feat;
|
||||
FeatureItem *item;
|
||||
GtkGesture *gesture;
|
||||
char *name;
|
||||
|
||||
tag = hb_tag_from_string (tags[i], -1);
|
||||
|
||||
name = get_feature_display_name (tag);
|
||||
feat = gtk_check_button_new_with_label (name);
|
||||
g_free (name);
|
||||
set_inconsistent (GTK_CHECK_BUTTON (feat), TRUE);
|
||||
g_signal_connect_swapped (feat, "notify::active", G_CALLBACK (update_display), self);
|
||||
g_signal_connect_swapped (feat, "notify::inconsistent", G_CALLBACK (update_display), self);
|
||||
g_signal_connect (feat, "toggled", G_CALLBACK (feat_toggled_cb), NULL);
|
||||
|
||||
gesture = gtk_gesture_click_new ();
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
|
||||
g_signal_connect (gesture, "pressed", G_CALLBACK (feat_pressed), feat);
|
||||
gtk_widget_add_controller (feat, GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
gtk_box_append (GTK_BOX (group), feat);
|
||||
|
||||
item = g_new (FeatureItem, 1);
|
||||
item->name = tags[i];
|
||||
item->tag = tag;
|
||||
item->feat = feat;
|
||||
|
||||
self->feature_items = g_list_prepend (self->feature_items, item);
|
||||
}
|
||||
|
||||
gtk_grid_attach (self->grid, group, 0, row, 2, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
add_radio_group (FontFeatures *self,
|
||||
const char *title,
|
||||
const char **tags,
|
||||
unsigned int n_tags,
|
||||
int row)
|
||||
{
|
||||
GtkWidget *group;
|
||||
int i;
|
||||
GtkWidget *group_button = NULL;
|
||||
|
||||
group = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_widget_set_halign (group, GTK_ALIGN_START);
|
||||
|
||||
gtk_box_append (GTK_BOX (group), make_title_label (title));
|
||||
|
||||
for (i = 0; i < n_tags; i++)
|
||||
{
|
||||
unsigned int tag;
|
||||
GtkWidget *feat;
|
||||
FeatureItem *item;
|
||||
char *name;
|
||||
|
||||
tag = hb_tag_from_string (tags[i], -1);
|
||||
name = get_feature_display_name (tag);
|
||||
feat = gtk_check_button_new_with_label (name ? name : _("Default"));
|
||||
g_free (name);
|
||||
if (group_button == NULL)
|
||||
group_button = feat;
|
||||
else
|
||||
gtk_check_button_set_group (GTK_CHECK_BUTTON (feat), GTK_CHECK_BUTTON (group_button));
|
||||
g_signal_connect_swapped (feat, "notify::active", G_CALLBACK (update_display), self);
|
||||
g_object_set_data (G_OBJECT (feat), "default", group_button);
|
||||
|
||||
gtk_box_append (GTK_BOX (group), feat);
|
||||
|
||||
item = g_new (FeatureItem, 1);
|
||||
item->name = tags[i];
|
||||
item->tag = tag;
|
||||
item->feat = feat;
|
||||
|
||||
self->feature_items = g_list_prepend (self->feature_items, item);
|
||||
}
|
||||
|
||||
gtk_grid_attach (self->grid, group, 0, row, 2, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_features (FontFeatures *self)
|
||||
{
|
||||
const char *kerning[] = { "kern" };
|
||||
const char *ligatures[] = { "liga", "dlig", "hlig", "clig", "rlig" };
|
||||
const char *letter_case[] = {
|
||||
"smcp", "c2sc", "pcap", "c2pc", "unic", "cpsp", "case"
|
||||
};
|
||||
const char *number_case[] = { "xxxx", "lnum", "onum" };
|
||||
const char *number_spacing[] = { "xxxx", "pnum", "tnum" };
|
||||
const char *fractions[] = { "xxxx", "frac", "afrc" };
|
||||
const char *num_extras[] = { "zero", "nalt", "sinf" };
|
||||
const char *char_alt[] = {
|
||||
"swsh", "cswh", "locl", "calt", "falt", "hist",
|
||||
"salt", "jalt", "titl", "rand", "subs", "sups",
|
||||
"ordn", "ltra", "ltrm", "rtla", "rtlm", "rclt"
|
||||
};
|
||||
const char *pos_alt[] = {
|
||||
"init", "medi", "med2", "fina", "fin2", "fin3", "isol"
|
||||
};
|
||||
const char *width_var[] = {
|
||||
"fwid", "hwid", "halt", "pwid", "palt", "twid", "qwid"
|
||||
};
|
||||
const char *style_alt[] = {
|
||||
"ss01", "ss02", "ss03", "ss04", "ss05", "ss06",
|
||||
"ss07", "ss08", "ss09", "ss10", "ss11", "ss12",
|
||||
"ss13", "ss14", "ss15", "ss16", "ss17", "ss18",
|
||||
"ss19", "ss20"
|
||||
};
|
||||
const char *char_var[] = {
|
||||
"cv01", "cv02", "cv03", "cv04", "cv05", "cv06",
|
||||
"cv07", "cv08", "cv09", "cv10", "cv11", "cv12",
|
||||
"cv13", "cv14", "cv15", "cv16", "cv17", "cv18",
|
||||
"cv19", "cv20"
|
||||
};
|
||||
const char *math[] = { "dtls", "flac", "mgrk", "ssty" };
|
||||
const char *bounds[] = { "opbd", "lfbd", "rtbd" };
|
||||
int row = 0;
|
||||
|
||||
add_check_group (self, _("Kerning"), kerning, G_N_ELEMENTS (kerning), row++);
|
||||
add_check_group (self, _("Ligatures"), ligatures, G_N_ELEMENTS (ligatures), row++);
|
||||
add_check_group (self, _("Letter Case"), letter_case, G_N_ELEMENTS (letter_case), row++);
|
||||
add_radio_group (self, _("Number Case"), number_case, G_N_ELEMENTS (number_case), row++);
|
||||
add_radio_group (self, _("Number Spacing"), number_spacing, G_N_ELEMENTS (number_spacing), row++);
|
||||
add_radio_group (self, _("Fractions"), fractions, G_N_ELEMENTS (fractions), row++);
|
||||
add_check_group (self, _("Numeric Extras"), num_extras, G_N_ELEMENTS (num_extras), row++);
|
||||
add_check_group (self, _("Character Alternatives"), char_alt, G_N_ELEMENTS (char_alt), row++);
|
||||
add_check_group (self, _("Positional Alternatives"), pos_alt, G_N_ELEMENTS (pos_alt), row++);
|
||||
add_check_group (self, _("Width Variants"), width_var, G_N_ELEMENTS (width_var), row++);
|
||||
add_check_group (self, _("Alternative Stylistic Sets"), style_alt, G_N_ELEMENTS (style_alt), row++);
|
||||
add_check_group (self, _("Character Variants"), char_var, G_N_ELEMENTS (char_var), row++);
|
||||
add_check_group (self, _("Mathematical"), math, G_N_ELEMENTS (math), row++);
|
||||
add_check_group (self, _("Optical Bounds"), bounds, G_N_ELEMENTS (bounds), row++);
|
||||
|
||||
self->feature_items = g_list_reverse (self->feature_items);
|
||||
}
|
||||
|
||||
static void
|
||||
reset (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
FontFeatures *self)
|
||||
{
|
||||
update_features (self);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FEATURES]);
|
||||
g_simple_action_set_enabled (self->reset_action, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
font_features_init (FontFeatures *self)
|
||||
{
|
||||
self->font_map = g_object_ref (pango2_font_map_get_default ());
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
self->font_desc = pango2_font_description_from_string ("sans 12");
|
||||
self->lang = pango2_language_get_default ();
|
||||
|
||||
setup_features (self);
|
||||
|
||||
self->reset_action = g_simple_action_new ("reset", NULL);
|
||||
g_simple_action_set_enabled (self->reset_action, FALSE);
|
||||
g_signal_connect (self->reset_action, "activate", G_CALLBACK (reset), self);
|
||||
}
|
||||
|
||||
static void
|
||||
font_features_dispose (GObject *object)
|
||||
{
|
||||
FontFeatures *self = FONT_FEATURES (object);
|
||||
|
||||
gtk_widget_clear_template (GTK_WIDGET (object), FONT_FEATURES_TYPE);
|
||||
|
||||
g_list_free_full (self->feature_items, g_free);
|
||||
|
||||
G_OBJECT_CLASS (font_features_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
font_features_finalize (GObject *object)
|
||||
{
|
||||
FontFeatures *self = FONT_FEATURES (object);
|
||||
|
||||
g_clear_pointer (&self->font_desc, pango2_font_description_free);
|
||||
g_clear_object (&self->font_map);
|
||||
|
||||
G_OBJECT_CLASS (font_features_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
font_features_set_property (GObject *object,
|
||||
unsigned int prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
FontFeatures *self = FONT_FEATURES (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FONT_MAP:
|
||||
g_set_object (&self->font_map, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_FONT_DESC:
|
||||
pango2_font_description_free (self->font_desc);
|
||||
self->font_desc = pango2_font_description_copy (g_value_get_boxed (value));
|
||||
break;
|
||||
|
||||
case PROP_LANGUAGE:
|
||||
self->lang = pango2_language_from_string (g_value_get_string (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
|
||||
update_features (self);
|
||||
}
|
||||
|
||||
static void
|
||||
font_features_get_property (GObject *object,
|
||||
unsigned int prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
FontFeatures *self = FONT_FEATURES (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FONT_MAP:
|
||||
g_value_set_object (value, self->font_map);
|
||||
break;
|
||||
|
||||
case PROP_FEATURES:
|
||||
g_value_take_string (value, get_features (self));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
font_features_class_init (FontFeaturesClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->dispose = font_features_dispose;
|
||||
object_class->finalize = font_features_finalize;
|
||||
object_class->get_property = font_features_get_property;
|
||||
object_class->set_property = font_features_set_property;
|
||||
|
||||
properties[PROP_FONT_MAP] =
|
||||
g_param_spec_object ("font-map", "", "",
|
||||
PANGO2_TYPE_FONT_MAP,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_FONT_DESC] =
|
||||
g_param_spec_boxed ("font-desc", "", "",
|
||||
PANGO2_TYPE_FONT_DESCRIPTION,
|
||||
G_PARAM_WRITABLE);
|
||||
|
||||
properties[PROP_LANGUAGE] =
|
||||
g_param_spec_string ("language", "", "",
|
||||
"en",
|
||||
G_PARAM_WRITABLE);
|
||||
|
||||
properties[PROP_FEATURES] =
|
||||
g_param_spec_string ("features", "", "",
|
||||
"",
|
||||
G_PARAM_READABLE);
|
||||
|
||||
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/fontexplorer/fontfeatures.ui");
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontFeatures, grid);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontFeatures, label);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), script_changed);
|
||||
|
||||
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "fontfeatures");
|
||||
}
|
||||
|
||||
GAction *
|
||||
font_features_get_reset_action (FontFeatures *self)
|
||||
{
|
||||
return G_ACTION (self->reset_action);
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define FONT_FEATURES_TYPE (font_features_get_type ())
|
||||
#define FONT_FEATURES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_FEATURES_TYPE, FontFeatures))
|
||||
|
||||
|
||||
typedef struct _FontFeatures FontFeatures;
|
||||
typedef struct _FontFeaturesClass FontFeaturesClass;
|
||||
|
||||
|
||||
GType font_features_get_type (void);
|
||||
GAction * font_features_get_reset_action (FontFeatures *self);
|
||||
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="FontFeatures" parent="GtkWidget">
|
||||
<property name="layout-manager"><object class="GtkBinLayout"/></property>
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid">
|
||||
<child>
|
||||
<object class="GtkLabel" id="label">
|
||||
<property name="label" translatable="yes">Features</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="heading"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="row">-1</property>
|
||||
<property name="column">0</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -1,508 +0,0 @@
|
||||
#include "fontvariations.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <hb-ot.h>
|
||||
|
||||
#include "rangeedit.h"
|
||||
|
||||
enum {
|
||||
PROP_FONT_MAP = 1,
|
||||
PROP_FONT_DESC,
|
||||
PROP_VARIATIONS,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
struct _FontVariations
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
GtkGrid *label;
|
||||
GtkGrid *grid;
|
||||
Pango2FontDescription *font_desc;
|
||||
GSimpleAction *reset_action;
|
||||
gboolean has_variations;
|
||||
|
||||
GtkWidget *instance_combo;
|
||||
GHashTable *axes;
|
||||
GHashTable *instances;
|
||||
|
||||
Pango2FontMap *font_map;
|
||||
};
|
||||
|
||||
struct _FontVariationsClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FontVariations, font_variations, GTK_TYPE_WIDGET);
|
||||
|
||||
static Pango2Font *
|
||||
get_font (FontVariations *self)
|
||||
{
|
||||
Pango2Context *context;
|
||||
Pango2Font *font;
|
||||
|
||||
context = pango2_context_new_with_font_map (self->font_map);
|
||||
font = pango2_context_load_font (context, self->font_desc);
|
||||
g_object_unref (context);
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
guint32 tag;
|
||||
GtkAdjustment *adjustment;
|
||||
double default_value;
|
||||
} Axis;
|
||||
|
||||
static guint
|
||||
axes_hash (gconstpointer v)
|
||||
{
|
||||
const Axis *p = v;
|
||||
|
||||
return p->tag;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
axes_equal (gconstpointer v1, gconstpointer v2)
|
||||
{
|
||||
const Axis *p1 = v1;
|
||||
const Axis *p2 = v2;
|
||||
|
||||
return p1->tag == p2->tag;
|
||||
}
|
||||
|
||||
static void
|
||||
unset_instance (GtkAdjustment *adjustment,
|
||||
FontVariations *self)
|
||||
{
|
||||
if (self->instance_combo)
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (self->instance_combo), 0);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_VARIATIONS]);
|
||||
g_simple_action_set_enabled (self->reset_action, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
add_axis (FontVariations *self,
|
||||
hb_face_t *hb_face,
|
||||
hb_ot_var_axis_info_t *ax,
|
||||
int i)
|
||||
{
|
||||
GtkWidget *axis_label;
|
||||
GtkWidget *axis_scale;
|
||||
GtkAdjustment *adjustment;
|
||||
Axis *axis;
|
||||
char name[20];
|
||||
unsigned int name_len = 20;
|
||||
|
||||
hb_ot_name_get_utf8 (hb_face, ax->name_id, HB_LANGUAGE_INVALID, &name_len, name);
|
||||
|
||||
axis_label = gtk_label_new (name);
|
||||
gtk_widget_set_halign (axis_label, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (axis_label, GTK_ALIGN_BASELINE);
|
||||
gtk_grid_attach (self->grid, axis_label, 0, i, 1, 1);
|
||||
adjustment = gtk_adjustment_new (ax->default_value, ax->min_value, ax->max_value,
|
||||
1.0, 10.0, 0.0);
|
||||
axis_scale = g_object_new (RANGE_EDIT_TYPE,
|
||||
"adjustment", adjustment,
|
||||
"default-value", ax->default_value,
|
||||
"n-chars", 5,
|
||||
"hexpand", TRUE,
|
||||
"halign", GTK_ALIGN_FILL,
|
||||
"valign", GTK_ALIGN_BASELINE,
|
||||
NULL);
|
||||
gtk_grid_attach (self->grid, axis_scale, 1, i, 1, 1);
|
||||
|
||||
axis = g_new0 (Axis, 1);
|
||||
axis->tag = ax->tag;
|
||||
axis->adjustment = adjustment;
|
||||
axis->default_value = ax->default_value;
|
||||
g_hash_table_add (self->axes, axis);
|
||||
|
||||
g_signal_connect (adjustment, "value-changed", G_CALLBACK (unset_instance), self);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
unsigned int index;
|
||||
} Instance;
|
||||
|
||||
static guint
|
||||
instance_hash (gconstpointer v)
|
||||
{
|
||||
const Instance *p = v;
|
||||
|
||||
return g_str_hash (p->name);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
instance_equal (gconstpointer v1, gconstpointer v2)
|
||||
{
|
||||
const Instance *p1 = v1;
|
||||
const Instance *p2 = v2;
|
||||
|
||||
return g_str_equal (p1->name, p2->name);
|
||||
}
|
||||
|
||||
static void
|
||||
free_instance (gpointer data)
|
||||
{
|
||||
Instance *instance = data;
|
||||
|
||||
g_free (instance->name);
|
||||
g_free (instance);
|
||||
}
|
||||
|
||||
static void
|
||||
add_instance (FontVariations *self,
|
||||
hb_face_t *face,
|
||||
unsigned int index,
|
||||
GtkWidget *combo,
|
||||
int pos)
|
||||
{
|
||||
Instance *instance;
|
||||
hb_ot_name_id_t name_id;
|
||||
char name[20];
|
||||
unsigned int name_len = 20;
|
||||
|
||||
instance = g_new0 (Instance, 1);
|
||||
|
||||
name_id = hb_ot_var_named_instance_get_subfamily_name_id (face, index);
|
||||
hb_ot_name_get_utf8 (face, name_id, HB_LANGUAGE_INVALID, &name_len, name);
|
||||
|
||||
instance->name = g_strdup (name);
|
||||
instance->index = index;
|
||||
|
||||
g_hash_table_add (self->instances, instance);
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), instance->name);
|
||||
}
|
||||
|
||||
static void
|
||||
instance_changed (GtkComboBox *combo,
|
||||
FontVariations *self)
|
||||
{
|
||||
char *text;
|
||||
Instance *instance;
|
||||
Instance ikey;
|
||||
int i;
|
||||
unsigned int coords_length;
|
||||
float *coords = NULL;
|
||||
hb_ot_var_axis_info_t *ai = NULL;
|
||||
unsigned int n_axes;
|
||||
Pango2Font *font = NULL;
|
||||
hb_font_t *hb_font;
|
||||
hb_face_t *hb_face;
|
||||
|
||||
text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (combo));
|
||||
if (text[0] == '\0')
|
||||
goto out;
|
||||
|
||||
ikey.name = text;
|
||||
instance = g_hash_table_lookup (self->instances, &ikey);
|
||||
if (!instance)
|
||||
{
|
||||
g_print ("did not find instance %s\n", text);
|
||||
goto out;
|
||||
}
|
||||
|
||||
font = get_font (self);
|
||||
hb_font = pango2_font_get_hb_font (font);
|
||||
hb_face = hb_font_get_face (hb_font);
|
||||
|
||||
n_axes = hb_ot_var_get_axis_infos (hb_face, 0, NULL, NULL);
|
||||
ai = g_new (hb_ot_var_axis_info_t, n_axes);
|
||||
hb_ot_var_get_axis_infos (hb_face, 0, &n_axes, ai);
|
||||
|
||||
coords = g_new (float, n_axes);
|
||||
hb_ot_var_named_instance_get_design_coords (hb_face,
|
||||
instance->index,
|
||||
&coords_length,
|
||||
coords);
|
||||
|
||||
for (i = 0; i < n_axes; i++)
|
||||
{
|
||||
Axis *axis;
|
||||
Axis akey;
|
||||
double value;
|
||||
|
||||
value = coords[ai[i].axis_index];
|
||||
|
||||
akey.tag = ai[i].tag;
|
||||
axis = g_hash_table_lookup (self->axes, &akey);
|
||||
if (axis)
|
||||
{
|
||||
g_signal_handlers_block_by_func (axis->adjustment, unset_instance, self);
|
||||
gtk_adjustment_set_value (axis->adjustment, value);
|
||||
g_signal_handlers_unblock_by_func (axis->adjustment, unset_instance, self);
|
||||
}
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_VARIATIONS]);
|
||||
g_simple_action_set_enabled (self->reset_action, TRUE);
|
||||
|
||||
out:
|
||||
g_free (text);
|
||||
g_clear_object (&font);
|
||||
g_free (ai);
|
||||
g_free (coords);
|
||||
}
|
||||
|
||||
static void
|
||||
update_variations (FontVariations *self)
|
||||
{
|
||||
GtkWidget *child;
|
||||
Pango2Font *font;
|
||||
hb_font_t *hb_font;
|
||||
hb_face_t *hb_face;
|
||||
unsigned int n_axes;
|
||||
hb_ot_var_axis_info_t *ai = NULL;
|
||||
int i;
|
||||
|
||||
font = get_font (self);
|
||||
hb_font = pango2_font_get_hb_font (font);
|
||||
hb_face = hb_font_get_face (hb_font);
|
||||
|
||||
g_object_ref (self->label);
|
||||
|
||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (self->grid))))
|
||||
gtk_grid_remove (self->grid, child);
|
||||
|
||||
gtk_grid_attach (self->grid, GTK_WIDGET (self->label), 0, -2, 2, 1);
|
||||
g_object_unref (self->label);
|
||||
|
||||
self->instance_combo = NULL;
|
||||
g_hash_table_remove_all (self->axes);
|
||||
g_hash_table_remove_all (self->instances);
|
||||
|
||||
n_axes = hb_ot_var_get_axis_infos (hb_face, 0, NULL, NULL);
|
||||
self->has_variations = n_axes > 0;
|
||||
gtk_widget_set_visible (GTK_WIDGET (self), self->has_variations);
|
||||
if (!self->has_variations)
|
||||
{
|
||||
g_simple_action_set_enabled (self->reset_action, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (hb_ot_var_get_named_instance_count (hb_face) > 0)
|
||||
{
|
||||
GtkWidget *label;
|
||||
GtkWidget *combo;
|
||||
|
||||
label = gtk_label_new ("Instance");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
|
||||
gtk_grid_attach (self->grid, label, 0, -1, 1, 1);
|
||||
|
||||
combo = gtk_combo_box_text_new ();
|
||||
gtk_widget_set_halign (combo, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (combo, GTK_ALIGN_BASELINE);
|
||||
gtk_widget_set_hexpand (combo, TRUE);
|
||||
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "");
|
||||
|
||||
for (i = 0; i < hb_ot_var_get_named_instance_count (hb_face); i++)
|
||||
add_instance (self, hb_face, i, combo, i);
|
||||
|
||||
gtk_grid_attach (GTK_GRID (self->grid), combo, 1, -1, 1, 1);
|
||||
g_signal_connect (combo, "changed", G_CALLBACK (instance_changed), self);
|
||||
self->instance_combo = combo;
|
||||
}
|
||||
|
||||
ai = g_new (hb_ot_var_axis_info_t, n_axes);
|
||||
hb_ot_var_get_axis_infos (hb_face, 0, &n_axes, ai);
|
||||
for (i = 0; i < n_axes; i++)
|
||||
add_axis (self, hb_face, &ai[i], i);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_VARIATIONS]);
|
||||
|
||||
g_clear_object (&font);
|
||||
g_free (ai);
|
||||
}
|
||||
|
||||
static char *
|
||||
get_variations (FontVariations *self)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
Axis *axis;
|
||||
char buf[G_ASCII_DTOSTR_BUF_SIZE];
|
||||
const char *sep = "";
|
||||
GString *s;
|
||||
|
||||
if (!self->has_variations)
|
||||
return g_strdup ("");
|
||||
|
||||
s = g_string_new ("");
|
||||
|
||||
g_hash_table_iter_init (&iter, self->axes);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)NULL, (gpointer *)&axis))
|
||||
{
|
||||
char tag[5];
|
||||
double value;
|
||||
|
||||
hb_tag_to_string (axis->tag, tag);
|
||||
tag[4] = '\0';
|
||||
value = gtk_adjustment_get_value (axis->adjustment);
|
||||
|
||||
g_string_append_printf (s, "%s%s=%s", sep, tag, g_ascii_dtostr (buf, sizeof (buf), value));
|
||||
sep = ",";
|
||||
}
|
||||
|
||||
return g_string_free (s, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
reset (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
FontVariations *self)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
Axis *axis;
|
||||
|
||||
if (self->instance_combo)
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (self->instance_combo), 0);
|
||||
|
||||
g_hash_table_iter_init (&iter, self->axes);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)NULL, (gpointer *)&axis))
|
||||
{
|
||||
g_signal_handlers_block_by_func (axis->adjustment, unset_instance, self);
|
||||
gtk_adjustment_set_value (axis->adjustment, axis->default_value);
|
||||
g_signal_handlers_unblock_by_func (axis->adjustment, unset_instance, self);
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_VARIATIONS]);
|
||||
g_simple_action_set_enabled (self->reset_action, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
font_variations_init (FontVariations *self)
|
||||
{
|
||||
self->font_map = g_object_ref (pango2_font_map_get_default ());
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
self->reset_action = g_simple_action_new ("reset", NULL);
|
||||
g_simple_action_set_enabled (self->reset_action, FALSE);
|
||||
g_signal_connect (self->reset_action, "activate", G_CALLBACK (reset), self);
|
||||
|
||||
self->instances = g_hash_table_new_full (instance_hash, instance_equal,
|
||||
NULL, free_instance);
|
||||
self->axes = g_hash_table_new_full (axes_hash, axes_equal,
|
||||
NULL, g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
font_variations_dispose (GObject *object)
|
||||
{
|
||||
FontVariations *self = FONT_VARIATIONS (object);
|
||||
|
||||
gtk_widget_clear_template (GTK_WIDGET (object), FONT_VARIATIONS_TYPE);
|
||||
|
||||
g_hash_table_unref (self->instances);
|
||||
g_hash_table_unref (self->axes);
|
||||
|
||||
G_OBJECT_CLASS (font_variations_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
font_variations_finalize (GObject *object)
|
||||
{
|
||||
FontVariations *self = FONT_VARIATIONS (object);
|
||||
|
||||
g_clear_pointer (&self->font_desc, pango2_font_description_free);
|
||||
g_clear_object (&self->font_map);
|
||||
|
||||
G_OBJECT_CLASS (font_variations_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
font_variations_set_property (GObject *object,
|
||||
unsigned int prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
FontVariations *self = FONT_VARIATIONS (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FONT_MAP:
|
||||
g_set_object (&self->font_map, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_FONT_DESC:
|
||||
pango2_font_description_free (self->font_desc);
|
||||
self->font_desc = pango2_font_description_copy (g_value_get_boxed (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
|
||||
update_variations (self);
|
||||
}
|
||||
|
||||
static void
|
||||
font_variations_get_property (GObject *object,
|
||||
unsigned int prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
FontVariations *self = FONT_VARIATIONS (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FONT_MAP:
|
||||
g_value_set_object (value, self->font_map);
|
||||
break;
|
||||
|
||||
case PROP_VARIATIONS:
|
||||
g_value_take_string (value, get_variations (self));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
font_variations_class_init (FontVariationsClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->dispose = font_variations_dispose;
|
||||
object_class->finalize = font_variations_finalize;
|
||||
object_class->get_property = font_variations_get_property;
|
||||
object_class->set_property = font_variations_set_property;
|
||||
|
||||
properties[PROP_FONT_MAP] =
|
||||
g_param_spec_object ("font-map", "", "",
|
||||
PANGO2_TYPE_FONT_MAP,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_FONT_DESC] =
|
||||
g_param_spec_boxed ("font-desc", "", "",
|
||||
PANGO2_TYPE_FONT_DESCRIPTION,
|
||||
G_PARAM_WRITABLE);
|
||||
|
||||
properties[PROP_VARIATIONS] =
|
||||
g_param_spec_string ("variations", "", "",
|
||||
"",
|
||||
G_PARAM_READABLE);
|
||||
|
||||
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/fontexplorer/fontvariations.ui");
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontVariations, grid);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontVariations, label);
|
||||
|
||||
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "fontvariations");
|
||||
}
|
||||
|
||||
GAction *
|
||||
font_variations_get_reset_action (FontVariations *self)
|
||||
{
|
||||
return G_ACTION (self->reset_action);
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define FONT_VARIATIONS_TYPE (font_variations_get_type ())
|
||||
#define FONT_VARIATIONS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_VARIATIONS_TYPE, FontVariations))
|
||||
|
||||
|
||||
typedef struct _FontVariations FontVariations;
|
||||
typedef struct _FontVariationsClass FontVariationsClass;
|
||||
|
||||
|
||||
GType font_variations_get_type (void);
|
||||
GAction * font_variations_get_reset_action (FontVariations *self);
|
||||
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="FontVariations" parent="GtkWidget">
|
||||
<property name="layout-manager"><object class="GtkBinLayout"/></property>
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid">
|
||||
<child>
|
||||
<object class="GtkLabel" id="label">
|
||||
<property name="label" translatable="yes">Variations</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="heading"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="row">-2</property>
|
||||
<property name="column">0</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -1,56 +0,0 @@
|
||||
#include "glyphitem.h"
|
||||
|
||||
struct _GlyphItem {
|
||||
GObject parent;
|
||||
Pango2Font *font;
|
||||
hb_codepoint_t glyph;
|
||||
};
|
||||
|
||||
struct _GlyphItemClass {
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GlyphItem, glyph_item, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
glyph_item_init (GlyphItem *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
glyph_item_finalize (GObject *object)
|
||||
{
|
||||
GlyphItem *item = GLYPH_ITEM (object);
|
||||
|
||||
g_object_unref (item->font);
|
||||
|
||||
G_OBJECT_CLASS (glyph_item_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
glyph_item_class_init (GlyphItemClass *class)
|
||||
{
|
||||
G_OBJECT_CLASS (class)->finalize = glyph_item_finalize;
|
||||
}
|
||||
|
||||
GlyphItem *
|
||||
glyph_item_new (Pango2Font *font,
|
||||
hb_codepoint_t glyph)
|
||||
{
|
||||
GlyphItem *item = g_object_new (GLYPH_ITEM_TYPE, NULL);
|
||||
item->font = g_object_ref (font);
|
||||
item->glyph = glyph;
|
||||
return item;
|
||||
}
|
||||
|
||||
Pango2Font *
|
||||
glyph_item_get_font (GlyphItem *item)
|
||||
{
|
||||
return item->font;
|
||||
}
|
||||
|
||||
hb_codepoint_t
|
||||
glyph_item_get_glyph (GlyphItem *item)
|
||||
{
|
||||
return item->glyph;
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define GLYPH_ITEM_TYPE (glyph_item_get_type ())
|
||||
#define GLYPH_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLYPH_ITEM_TYPE, GlyphItem))
|
||||
|
||||
|
||||
typedef struct _GlyphItem GlyphItem;
|
||||
typedef struct _GlyphItemClass GlyphItemClass;
|
||||
|
||||
|
||||
GType glyph_item_get_type (void);
|
||||
GlyphItem * glyph_item_new (Pango2Font *font,
|
||||
hb_codepoint_t glyph);
|
||||
hb_codepoint_t glyph_item_get_glyph (GlyphItem *item);
|
||||
Pango2Font * glyph_item_get_font (GlyphItem *item);
|
||||
@@ -1,97 +0,0 @@
|
||||
#include "glyphmodel.h"
|
||||
|
||||
#include "glyphitem.h"
|
||||
|
||||
struct _GlyphModel {
|
||||
GObject parent;
|
||||
Pango2Font *font;
|
||||
unsigned int num_glyphs;
|
||||
GlyphItem **glyphs;
|
||||
};
|
||||
|
||||
struct _GlyphModelClass {
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
static GType
|
||||
glyph_model_get_item_type (GListModel *model)
|
||||
{
|
||||
return GLYPH_ITEM_TYPE;
|
||||
}
|
||||
|
||||
static guint
|
||||
glyph_model_get_n_items (GListModel *model)
|
||||
{
|
||||
GlyphModel *self = GLYPH_MODEL (model);
|
||||
|
||||
return self->num_glyphs;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
glyph_model_get_item (GListModel *model,
|
||||
guint position)
|
||||
{
|
||||
GlyphModel *self = GLYPH_MODEL (model);
|
||||
|
||||
if (position >= self->num_glyphs)
|
||||
return NULL;
|
||||
|
||||
if (self->glyphs[position] == NULL)
|
||||
self->glyphs[position] = glyph_item_new (self->font, position);
|
||||
|
||||
return g_object_ref (self->glyphs[position]);
|
||||
}
|
||||
|
||||
static void
|
||||
glyph_model_list_model_init (GListModelInterface *iface)
|
||||
{
|
||||
iface->get_item_type = glyph_model_get_item_type;
|
||||
iface->get_n_items = glyph_model_get_n_items;
|
||||
iface->get_item = glyph_model_get_item;
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GlyphModel, glyph_model, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, glyph_model_list_model_init))
|
||||
|
||||
static void
|
||||
glyph_model_init (GlyphModel *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
glyph_model_finalize (GObject *object)
|
||||
{
|
||||
GlyphModel *self = GLYPH_MODEL (object);
|
||||
|
||||
g_object_unref (self->font);
|
||||
for (int i = 0; i < self->num_glyphs; i++)
|
||||
{
|
||||
if (self->glyphs[i])
|
||||
g_object_unref (self->glyphs[i]);
|
||||
}
|
||||
g_free (self->glyphs);
|
||||
|
||||
G_OBJECT_CLASS (glyph_model_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
glyph_model_class_init (GlyphModelClass *class)
|
||||
{
|
||||
G_OBJECT_CLASS (class)->finalize = glyph_model_finalize;
|
||||
}
|
||||
|
||||
GlyphModel *
|
||||
glyph_model_new (Pango2Font *font)
|
||||
{
|
||||
GlyphModel *self;
|
||||
hb_face_t *hb_face;
|
||||
|
||||
self = g_object_new (GLYPH_MODEL_TYPE, NULL);
|
||||
|
||||
self->font = g_object_ref (font);
|
||||
hb_face = pango2_hb_face_get_hb_face (PANGO2_HB_FACE (pango2_font_get_face (font)));
|
||||
self->num_glyphs = hb_face_get_glyph_count (hb_face);
|
||||
self->glyphs = g_new0 (GlyphItem *, self->num_glyphs);
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define GLYPH_MODEL_TYPE (glyph_model_get_type ())
|
||||
#define GLYPH_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLYPH_MODEL_TYPE, GlyphModel))
|
||||
|
||||
|
||||
typedef struct _GlyphModel GlyphModel;
|
||||
typedef struct _GlyphModelClass GlyphModelClass;
|
||||
|
||||
|
||||
GType glyph_model_get_type (void);
|
||||
GlyphModel * glyph_model_new (Pango2Font *font);
|
||||
@@ -1,239 +0,0 @@
|
||||
#include "glyphsview.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <hb-ot.h>
|
||||
|
||||
#include "glyphitem.h"
|
||||
#include "glyphmodel.h"
|
||||
#include "glyphview.h"
|
||||
|
||||
enum {
|
||||
PROP_FONT_MAP = 1,
|
||||
PROP_FONT_DESC,
|
||||
PROP_VARIATIONS,
|
||||
PROP_PALETTE,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
struct _GlyphsView
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
Pango2FontMap *font_map;
|
||||
GtkGridView *glyphs;
|
||||
|
||||
Pango2FontDescription *font_desc;
|
||||
char *variations;
|
||||
char *palette;
|
||||
GQuark palette_quark;
|
||||
};
|
||||
|
||||
struct _GlyphsViewClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(GlyphsView, glyphs_view, GTK_TYPE_WIDGET);
|
||||
|
||||
static void
|
||||
glyphs_view_init (GlyphsView *self)
|
||||
{
|
||||
self->font_map = g_object_ref (pango2_font_map_get_default ());
|
||||
self->font_desc = pango2_font_description_from_string ("sans 12");
|
||||
self->variations = g_strdup ("");
|
||||
self->palette = g_strdup (PANGO2_COLOR_PALETTE_DEFAULT);
|
||||
self->palette_quark = g_quark_from_string (self->palette);
|
||||
|
||||
gtk_widget_set_layout_manager (GTK_WIDGET (self),
|
||||
gtk_box_layout_new (GTK_ORIENTATION_VERTICAL));
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
glyphs_view_dispose (GObject *object)
|
||||
{
|
||||
gtk_widget_clear_template (GTK_WIDGET (object), GLYPHS_VIEW_TYPE);
|
||||
|
||||
G_OBJECT_CLASS (glyphs_view_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
glyphs_view_finalize (GObject *object)
|
||||
{
|
||||
GlyphsView *self = GLYPHS_VIEW (object);
|
||||
|
||||
g_clear_object (&self->font_map);
|
||||
pango2_font_description_free (self->font_desc);
|
||||
g_free (self->variations);
|
||||
g_free (self->palette);
|
||||
|
||||
G_OBJECT_CLASS (glyphs_view_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static Pango2Font *
|
||||
get_font (GlyphsView *self,
|
||||
int size)
|
||||
{
|
||||
Pango2Context *context;
|
||||
Pango2FontDescription *desc;
|
||||
Pango2Font *font;
|
||||
|
||||
context = pango2_context_new_with_font_map (self->font_map);
|
||||
desc = pango2_font_description_copy_static (self->font_desc);
|
||||
pango2_font_description_set_variations (desc, self->variations);
|
||||
pango2_font_description_set_size (desc, size);
|
||||
font = pango2_context_load_font (context, desc);
|
||||
pango2_font_description_free (desc);
|
||||
g_object_unref (context);
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
static void
|
||||
update_glyph_model (GlyphsView *self)
|
||||
{
|
||||
Pango2Font *font = get_font (self, 60 * PANGO2_SCALE);
|
||||
GlyphModel *gm;
|
||||
GtkSelectionModel *model;
|
||||
|
||||
gm = glyph_model_new (font);
|
||||
model = GTK_SELECTION_MODEL (gtk_no_selection_new (G_LIST_MODEL (gm)));
|
||||
gtk_grid_view_set_model (self->glyphs, model);
|
||||
g_object_unref (model);
|
||||
g_object_unref (font);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_glyph (GtkSignalListItemFactory *factory,
|
||||
GObject *listitem)
|
||||
{
|
||||
gtk_list_item_set_child (GTK_LIST_ITEM (listitem), GTK_WIDGET (glyph_view_new ()));
|
||||
}
|
||||
|
||||
static void
|
||||
bind_glyph (GtkSignalListItemFactory *factory,
|
||||
GObject *listitem,
|
||||
GlyphsView *self)
|
||||
{
|
||||
GlyphView *view;
|
||||
GObject *item;
|
||||
|
||||
view = GLYPH_VIEW (gtk_list_item_get_child (GTK_LIST_ITEM (listitem)));
|
||||
item = gtk_list_item_get_item (GTK_LIST_ITEM (listitem));
|
||||
glyph_view_set_font (view, glyph_item_get_font (GLYPH_ITEM (item)));
|
||||
glyph_view_set_glyph (view, glyph_item_get_glyph (GLYPH_ITEM (item)));
|
||||
glyph_view_set_palette (view, self->palette_quark);
|
||||
}
|
||||
|
||||
static void
|
||||
glyphs_view_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GlyphsView *self = GLYPHS_VIEW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FONT_MAP:
|
||||
g_set_object (&self->font_map, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_FONT_DESC:
|
||||
pango2_font_description_free (self->font_desc);
|
||||
self->font_desc = pango2_font_description_copy (g_value_get_boxed (value));
|
||||
break;
|
||||
|
||||
case PROP_VARIATIONS:
|
||||
g_free (self->variations);
|
||||
self->variations = g_strdup (g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_PALETTE:
|
||||
g_free (self->palette);
|
||||
self->palette = g_strdup (g_value_get_string (value));
|
||||
self->palette_quark = g_quark_from_string (self->palette);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
|
||||
update_glyph_model (self);
|
||||
}
|
||||
|
||||
static void
|
||||
glyphs_view_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GlyphsView *self = GLYPHS_VIEW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FONT_MAP:
|
||||
g_value_set_object (value, self->font_map);
|
||||
break;
|
||||
|
||||
case PROP_FONT_DESC:
|
||||
g_value_set_boxed (value, self->font_desc);
|
||||
break;
|
||||
|
||||
case PROP_VARIATIONS:
|
||||
g_value_set_string (value, self->variations);
|
||||
break;
|
||||
|
||||
case PROP_PALETTE:
|
||||
g_value_set_string (value, self->palette);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
glyphs_view_class_init (GlyphsViewClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->dispose = glyphs_view_dispose;
|
||||
object_class->finalize = glyphs_view_finalize;
|
||||
object_class->get_property = glyphs_view_get_property;
|
||||
object_class->set_property = glyphs_view_set_property;
|
||||
|
||||
properties[PROP_FONT_MAP] =
|
||||
g_param_spec_object ("font-map", "", "",
|
||||
PANGO2_TYPE_FONT_MAP,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_FONT_DESC] =
|
||||
g_param_spec_boxed ("font-desc", "", "",
|
||||
PANGO2_TYPE_FONT_DESCRIPTION,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_VARIATIONS] =
|
||||
g_param_spec_string ("variations", "", "",
|
||||
"",
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_PALETTE] =
|
||||
g_param_spec_string ("palette", "", "",
|
||||
PANGO2_COLOR_PALETTE_DEFAULT,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/fontexplorer/glyphsview.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), GlyphsView, glyphs);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), setup_glyph);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), bind_glyph);
|
||||
|
||||
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "glyphsview");
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define GLYPHS_VIEW_TYPE (glyphs_view_get_type ())
|
||||
#define GLYPHS_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLYPHS_VIEW_TYPE, GlyphsView))
|
||||
|
||||
|
||||
typedef struct _GlyphsView GlyphsView;
|
||||
typedef struct _GlyphsViewClass GlyphsViewClass;
|
||||
|
||||
|
||||
GType glyphs_view_get_type (void);
|
||||
@@ -1,29 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="GlyphsView" parent="GtkWidget">
|
||||
<style>
|
||||
<class name="view"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="vscrollbar-policy">automatic</property>
|
||||
<child>
|
||||
<object class="GtkGridView" id="glyphs">
|
||||
<style>
|
||||
<class name="content"/>
|
||||
</style>
|
||||
<property name="factory">
|
||||
<object class="GtkSignalListItemFactory">
|
||||
<signal name="setup" handler="setup_glyph"/>
|
||||
<signal name="bind" handler="bind_glyph"/>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -1,321 +0,0 @@
|
||||
#include "glyphview.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <hb-ot.h>
|
||||
|
||||
struct _GlyphView
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
Pango2Font *font;
|
||||
GQuark palette;
|
||||
int palette_index;
|
||||
hb_codepoint_t glyph;
|
||||
int n_layers;
|
||||
int layer;
|
||||
};
|
||||
|
||||
struct _GlyphViewClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(GlyphView, glyph_view, GTK_TYPE_WIDGET);
|
||||
|
||||
static void
|
||||
click_cb (GtkGestureClick *gesture,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
GlyphView *self)
|
||||
{
|
||||
if (self->n_layers == 0)
|
||||
return;
|
||||
|
||||
self->layer++;
|
||||
|
||||
if (self->layer == self->n_layers)
|
||||
self->layer = -1;
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
glyph_view_init (GlyphView *self)
|
||||
{
|
||||
GtkGesture *click;
|
||||
|
||||
self->n_layers = 0;
|
||||
self->layer = -1;
|
||||
|
||||
click = gtk_gesture_click_new ();
|
||||
g_signal_connect (click, "pressed", G_CALLBACK (click_cb), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (click));
|
||||
}
|
||||
|
||||
static void
|
||||
glyph_view_dispose (GObject *object)
|
||||
{
|
||||
GlyphView *self = GLYPH_VIEW (object);
|
||||
|
||||
g_clear_object (&self->font);
|
||||
|
||||
G_OBJECT_CLASS (glyph_view_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
glyph_view_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
GlyphView *self = GLYPH_VIEW (widget);
|
||||
Pango2GlyphString *glyphs;
|
||||
Pango2Rectangle ink, logical;
|
||||
cairo_t *cr;
|
||||
int width, height;
|
||||
char name[80];
|
||||
|
||||
pango2_font_get_glyph_extents (self->font, self->glyph, &ink, &logical);
|
||||
|
||||
width = gtk_widget_get_width (widget);
|
||||
height = gtk_widget_get_height (widget);
|
||||
|
||||
cr = gtk_snapshot_append_cairo (snapshot, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
|
||||
glyphs = pango2_glyph_string_new ();
|
||||
pango2_glyph_string_set_size (glyphs, 1);
|
||||
|
||||
glyphs->glyphs[0].geometry.width = ink.width;
|
||||
glyphs->glyphs[0].geometry.x_offset = ink.x;
|
||||
glyphs->glyphs[0].geometry.y_offset = -ink.y;
|
||||
|
||||
if (self->layer == -1)
|
||||
{
|
||||
glyphs->glyphs[0].glyph = self->glyph;
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
hb_face_t *face = hb_font_get_face (pango2_font_get_hb_font (self->font));
|
||||
hb_ot_color_layer_t *layers;
|
||||
unsigned int count;
|
||||
|
||||
layers = g_newa (hb_ot_color_layer_t, self->n_layers);
|
||||
count = self->n_layers;
|
||||
hb_ot_color_glyph_get_layers (face,
|
||||
self->glyph,
|
||||
0,
|
||||
&count,
|
||||
layers);
|
||||
glyphs->glyphs[0].glyph = layers[self->layer].glyph;
|
||||
if (layers[self->layer].color_index == 0xffff)
|
||||
{
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
hb_color_t *colors;
|
||||
unsigned int n_colors;
|
||||
hb_color_t color;
|
||||
|
||||
n_colors = hb_ot_color_palette_get_colors (face,
|
||||
self->palette_index,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
colors = g_newa (hb_color_t, n_colors);
|
||||
hb_ot_color_palette_get_colors (face,
|
||||
self->palette_index,
|
||||
0,
|
||||
&n_colors,
|
||||
colors);
|
||||
color = colors[layers[self->layer].color_index];
|
||||
cairo_set_source_rgba (cr, hb_color_get_red (color)/255.,
|
||||
hb_color_get_green (color)/255.,
|
||||
hb_color_get_blue (color)/255.,
|
||||
hb_color_get_alpha (color)/255.);
|
||||
}
|
||||
}
|
||||
|
||||
cairo_move_to (cr, (width - logical.width/1024.)/2, (height - logical.height/1024.)/2);
|
||||
pango2_cairo_show_color_glyph_string (cr, self->font, self->palette, glyphs);
|
||||
|
||||
{
|
||||
Pango2Layout *layout;
|
||||
Pango2FontDescription *desc;
|
||||
char gid[20];
|
||||
hb_font_t *hb_font;
|
||||
hb_face_t *hb_face;
|
||||
|
||||
g_snprintf (gid, sizeof (gid), "%d", self->glyph);
|
||||
layout = gtk_widget_create_pango_layout (widget, gid);
|
||||
desc = pango2_font_description_from_string ("Cantarell 8");
|
||||
pango2_layout_set_font_description (layout, desc);
|
||||
pango2_font_description_free (desc);
|
||||
|
||||
gtk_snapshot_save (snapshot);
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (5, 5));
|
||||
gtk_snapshot_append_layout (snapshot, layout, &(GdkRGBA){ 0.,0.,0.,0.7});
|
||||
gtk_snapshot_restore (snapshot);
|
||||
|
||||
hb_font = pango2_font_get_hb_font (self->font);
|
||||
hb_face = hb_font_get_face (hb_font);
|
||||
|
||||
if (hb_ot_layout_has_glyph_classes (hb_face))
|
||||
{
|
||||
hb_ot_layout_glyph_class_t class;
|
||||
const char *class_names[] = {
|
||||
NULL, "Base", "Ligature", "Mark", "Component"
|
||||
};
|
||||
int w, h;
|
||||
|
||||
class = hb_ot_layout_get_glyph_class (hb_face, self->glyph);
|
||||
|
||||
if (class != HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED)
|
||||
{
|
||||
pango2_layout_set_text (layout, class_names[class], -1);
|
||||
pango2_lines_get_size (pango2_layout_get_lines (layout), &w, &h);
|
||||
|
||||
gtk_snapshot_save (snapshot);
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (width - w/1024. - 5, 5));
|
||||
gtk_snapshot_append_layout (snapshot, layout, &(GdkRGBA){ 0.,0.,0.,.7});
|
||||
gtk_snapshot_restore (snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
if (hb_font_get_glyph_name (hb_font, self->glyph, name, sizeof (name)))
|
||||
{
|
||||
int w, h;
|
||||
|
||||
pango2_layout_set_text (layout, name, -1);
|
||||
pango2_lines_get_size (pango2_layout_get_lines (layout), &w, &h);
|
||||
|
||||
gtk_snapshot_save (snapshot);
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (5, height - h/1024. - 5));
|
||||
gtk_snapshot_append_layout (snapshot, layout, &(GdkRGBA){ 0.,0.,0.,.7});
|
||||
gtk_snapshot_restore (snapshot);
|
||||
}
|
||||
|
||||
if (self->n_layers > 0)
|
||||
{
|
||||
char buf[128];
|
||||
int w, h;
|
||||
|
||||
if (self->layer == -1)
|
||||
g_snprintf (buf, sizeof (buf), "%d Layers", self->n_layers);
|
||||
else
|
||||
g_snprintf (buf, sizeof (buf), "Layer %d", self->layer);
|
||||
|
||||
pango2_layout_set_text (layout, buf, -1);
|
||||
pango2_lines_get_size (pango2_layout_get_lines (layout), &w, &h);
|
||||
|
||||
gtk_snapshot_save (snapshot);
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (width - w/1024. - 5, height - h/1024. - 5));
|
||||
gtk_snapshot_append_layout (snapshot, layout, &(GdkRGBA){ 0.,0.,0.,.7});
|
||||
gtk_snapshot_restore (snapshot);
|
||||
}
|
||||
|
||||
g_object_unref (layout);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
glyph_view_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
GlyphView *self = GLYPH_VIEW (widget);
|
||||
Pango2Rectangle ink, logical;
|
||||
|
||||
pango2_font_get_glyph_extents (self->font, self->glyph, &ink, &logical);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
*minimum = *natural = 2 * logical.width / PANGO2_SCALE;
|
||||
else
|
||||
*minimum = *natural = 2 * logical.height / PANGO2_SCALE;
|
||||
}
|
||||
|
||||
static void
|
||||
glyph_view_class_init (GlyphViewClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
object_class->dispose = glyph_view_dispose;
|
||||
widget_class->snapshot = glyph_view_snapshot;
|
||||
widget_class->measure = glyph_view_measure;
|
||||
|
||||
gtk_widget_class_set_css_name (widget_class, "glyphview");
|
||||
}
|
||||
|
||||
GlyphView *
|
||||
glyph_view_new (void)
|
||||
{
|
||||
return g_object_new (GLYPH_VIEW_TYPE, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
glyph_view_set_font (GlyphView *self,
|
||||
Pango2Font *font)
|
||||
{
|
||||
if (g_set_object (&self->font, font))
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
find_palette_index_by_flag (hb_face_t *hbface,
|
||||
hb_ot_color_palette_flags_t flag)
|
||||
{
|
||||
unsigned int n_palettes;
|
||||
|
||||
n_palettes = hb_ot_color_palette_get_count (hbface);
|
||||
for (unsigned int i = 0; i < n_palettes; i++)
|
||||
{
|
||||
if (hb_ot_color_palette_get_flags (hbface, i) & flag)
|
||||
return i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
glyph_view_set_palette (GlyphView *self,
|
||||
GQuark palette)
|
||||
{
|
||||
if (self->palette == palette)
|
||||
return;
|
||||
|
||||
self->palette = palette;
|
||||
|
||||
if (palette == g_quark_from_string (PANGO2_COLOR_PALETTE_DEFAULT))
|
||||
self->palette_index = 0;
|
||||
else if (palette == g_quark_from_string (PANGO2_COLOR_PALETTE_LIGHT))
|
||||
self->palette_index = find_palette_index_by_flag (hb_font_get_face (pango2_font_get_hb_font (self->font)), HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_LIGHT_BACKGROUND);
|
||||
else if (palette == g_quark_from_string (PANGO2_COLOR_PALETTE_DARK))
|
||||
self->palette_index = find_palette_index_by_flag (hb_font_get_face (pango2_font_get_hb_font (self->font)), HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND);
|
||||
else
|
||||
{
|
||||
const char *str = g_quark_to_string (palette);
|
||||
char *endp;
|
||||
if (g_str_has_prefix (str, "palette"))
|
||||
self->palette_index = g_ascii_strtoll (str + strlen ("palette"), &endp, 10);
|
||||
}
|
||||
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
void
|
||||
glyph_view_set_glyph (GlyphView *self,
|
||||
hb_codepoint_t glyph)
|
||||
{
|
||||
if (self->glyph == glyph)
|
||||
return;
|
||||
|
||||
self->glyph = glyph;
|
||||
self->n_layers = hb_ot_color_glyph_get_layers (hb_font_get_face (pango2_font_get_hb_font (self->font)), glyph, 0, NULL, NULL);
|
||||
self->layer = -1;
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define GLYPH_VIEW_TYPE (glyph_view_get_type ())
|
||||
#define GLYPH_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLYPH_VIEW_TYPE, GlyphView))
|
||||
|
||||
|
||||
typedef struct _GlyphView GlyphView;
|
||||
typedef struct _GlyphViewClass GlyphViewClass;
|
||||
|
||||
|
||||
GType glyph_view_get_type (void);
|
||||
GlyphView * glyph_view_new (void);
|
||||
void glyph_view_set_font (GlyphView *view,
|
||||
Pango2Font *font);
|
||||
void glyph_view_set_palette (GlyphView *view,
|
||||
GQuark palette);
|
||||
void glyph_view_set_glyph (GlyphView *view,
|
||||
hb_codepoint_t glyph);
|
||||
@@ -1,423 +0,0 @@
|
||||
#include "infoview.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <hb-ot.h>
|
||||
|
||||
enum {
|
||||
PROP_FONT_MAP = 1,
|
||||
PROP_FONT_DESC,
|
||||
PROP_SIZE,
|
||||
PROP_VARIATIONS,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
struct _InfoView
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
GtkGrid *info;
|
||||
|
||||
Pango2FontMap *font_map;
|
||||
Pango2FontDescription *font_desc;
|
||||
float size;
|
||||
char *variations;
|
||||
};
|
||||
|
||||
struct _InfoViewClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(InfoView, info_view, GTK_TYPE_WIDGET);
|
||||
|
||||
static void
|
||||
info_view_init (InfoView *self)
|
||||
{
|
||||
self->font_map = g_object_ref (pango2_font_map_get_default ());
|
||||
self->font_desc = pango2_font_description_from_string ("sans 12");
|
||||
self->size = 12.;
|
||||
self->variations = g_strdup ("");
|
||||
|
||||
gtk_widget_set_layout_manager (GTK_WIDGET (self),
|
||||
gtk_box_layout_new (GTK_ORIENTATION_VERTICAL));
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
info_view_dispose (GObject *object)
|
||||
{
|
||||
gtk_widget_clear_template (GTK_WIDGET (object), INFO_VIEW_TYPE);
|
||||
|
||||
G_OBJECT_CLASS (info_view_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
info_view_finalize (GObject *object)
|
||||
{
|
||||
InfoView *self = INFO_VIEW (object);
|
||||
|
||||
g_clear_object (&self->font_map);
|
||||
pango2_font_description_free (self->font_desc);
|
||||
g_free (self->variations);
|
||||
|
||||
G_OBJECT_CLASS (info_view_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static Pango2Font *
|
||||
get_font (InfoView *self,
|
||||
int size)
|
||||
{
|
||||
Pango2Context *context;
|
||||
Pango2FontDescription *desc;
|
||||
Pango2Font *font;
|
||||
|
||||
context = pango2_context_new_with_font_map (self->font_map);
|
||||
desc = pango2_font_description_copy_static (self->font_desc);
|
||||
pango2_font_description_set_variations (desc, self->variations);
|
||||
pango2_font_description_set_size (desc, size);
|
||||
font = pango2_context_load_font (context, desc);
|
||||
pango2_font_description_free (desc);
|
||||
g_object_unref (context);
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
make_title_label (const char *title)
|
||||
{
|
||||
GtkWidget *label;
|
||||
|
||||
label = gtk_label_new (title);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
g_object_set (label, "margin-top", 10, "margin-bottom", 10, NULL);
|
||||
gtk_widget_add_css_class (label, "heading");
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
static void
|
||||
add_misc_line (InfoView *self,
|
||||
const char *title,
|
||||
const char *value,
|
||||
int row)
|
||||
{
|
||||
GtkWidget *label;
|
||||
|
||||
label = gtk_label_new (title);
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_START);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_widget_set_hexpand (label, TRUE);
|
||||
gtk_grid_attach (self->info, label, 0, row, 1, 1);
|
||||
|
||||
label = gtk_label_new (value);
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_END);
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_START);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 1);
|
||||
gtk_label_set_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_width_chars (GTK_LABEL (label), 40);
|
||||
gtk_label_set_max_width_chars (GTK_LABEL (label), 40);
|
||||
gtk_label_set_selectable (GTK_LABEL (label), TRUE);
|
||||
gtk_grid_attach (self->info, label, 1, row, 1, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
add_info_line (InfoView *self,
|
||||
hb_face_t *face,
|
||||
hb_ot_name_id_t name_id,
|
||||
const char *title,
|
||||
int row)
|
||||
{
|
||||
char info[256];
|
||||
unsigned int len = sizeof (info);
|
||||
|
||||
if (hb_ot_name_get_utf8 (face, name_id, HB_LANGUAGE_INVALID, &len, info) > 0)
|
||||
add_misc_line (self, title, info, row);
|
||||
}
|
||||
|
||||
static void
|
||||
add_metrics_line (InfoView *self,
|
||||
hb_font_t *font,
|
||||
hb_ot_metrics_tag_t metrics_tag,
|
||||
const char *title,
|
||||
int row)
|
||||
{
|
||||
hb_position_t pos;
|
||||
|
||||
if (hb_ot_metrics_get_position (font, metrics_tag, &pos))
|
||||
{
|
||||
char buf[128];
|
||||
|
||||
g_snprintf (buf, sizeof (buf), "%d", pos);
|
||||
add_misc_line (self, title, buf, row);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_style_line (InfoView *self,
|
||||
hb_font_t *font,
|
||||
hb_style_tag_t style_tag,
|
||||
const char *title,
|
||||
int row)
|
||||
{
|
||||
float value;
|
||||
char buf[16];
|
||||
|
||||
value = hb_style_get_value (font, style_tag);
|
||||
g_snprintf (buf, sizeof (buf), "%.2f", value);
|
||||
add_misc_line (self, title, buf, row);
|
||||
}
|
||||
|
||||
static void
|
||||
update_info (InfoView *self)
|
||||
{
|
||||
GtkWidget *child;
|
||||
int size = pango2_font_description_get_size (self->font_desc);
|
||||
Pango2Font *pango_font = get_font (self, MAX (size, 10 * PANGO2_SCALE));
|
||||
hb_font_t *font1 = pango2_font_get_hb_font (pango_font);
|
||||
hb_face_t *face = hb_font_get_face (font1);
|
||||
hb_font_t *font = hb_font_create_sub_font (font1);
|
||||
int row = 0;
|
||||
char buf[128];
|
||||
unsigned int count;
|
||||
GString *s;
|
||||
hb_tag_t *tables;
|
||||
const char *path;
|
||||
|
||||
hb_font_set_scale (font, hb_face_get_upem (face), hb_face_get_upem (face));
|
||||
|
||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (self->info))) != NULL)
|
||||
gtk_widget_unparent (child);
|
||||
|
||||
gtk_grid_attach (self->info, make_title_label ("General Info"), 0, row++, 2, 1);
|
||||
|
||||
path = pango2_hb_face_get_file (PANGO2_HB_FACE (pango2_font_get_face (pango_font)));
|
||||
if (path)
|
||||
add_misc_line (self, "File ", path, row++);
|
||||
|
||||
add_info_line (self, face, HB_OT_NAME_ID_FONT_FAMILY, "Font Family Name", row++);
|
||||
add_info_line (self, face, HB_OT_NAME_ID_FONT_SUBFAMILY, "Font Subfamily Name", row++);
|
||||
add_info_line (self, face, HB_OT_NAME_ID_UNIQUE_ID, "Unique Font Identifier", row++);
|
||||
add_info_line (self, face, HB_OT_NAME_ID_FULL_NAME, "Full Name", row++);
|
||||
add_info_line (self, face, HB_OT_NAME_ID_VERSION_STRING, "Version", row++);
|
||||
add_info_line (self, face, HB_OT_NAME_ID_POSTSCRIPT_NAME, "Postscript Name", row++);
|
||||
add_info_line (self, face, HB_OT_NAME_ID_TYPOGRAPHIC_FAMILY, "Typographic Family Name", row++);
|
||||
add_info_line (self, face, HB_OT_NAME_ID_TYPOGRAPHIC_SUBFAMILY, "Typographic Subfamily Name", row++);
|
||||
add_info_line (self, face, HB_OT_NAME_ID_MANUFACTURER, "Vendor ID", row++);
|
||||
add_info_line (self, face, HB_OT_NAME_ID_DESIGNER, "Designer", row++);
|
||||
add_info_line (self, face, HB_OT_NAME_ID_DESCRIPTION, "Description", row++);
|
||||
add_info_line (self, face, HB_OT_NAME_ID_COPYRIGHT, "Copyright", row++);
|
||||
|
||||
gtk_grid_attach (self->info, make_title_label ("Metrics"), 0, row++, 2, 1);
|
||||
g_snprintf (buf, sizeof (buf), "%d", hb_face_get_upem (face));
|
||||
add_misc_line (self, "Units per Em", buf, row++);
|
||||
add_metrics_line (self, font, HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER, "Ascender", row++);
|
||||
add_metrics_line (self, font, HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER, "Descender", row++);
|
||||
add_metrics_line (self, font, HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP, "Line Gap", row++);
|
||||
add_metrics_line (self, font, HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE, "Caret Rise", row++);
|
||||
add_metrics_line (self, font, HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN, "Caret Run", row++);
|
||||
add_metrics_line (self, font, HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET, "Caret Offset", row++);
|
||||
add_metrics_line (self, font, HB_OT_METRICS_TAG_X_HEIGHT, "x Height", row++);
|
||||
add_metrics_line (self, font, HB_OT_METRICS_TAG_CAP_HEIGHT, "Cap Height", row++);
|
||||
|
||||
add_metrics_line (self, font, HB_OT_METRICS_TAG_STRIKEOUT_SIZE, "Strikeout Size", row++);
|
||||
add_metrics_line (self, font, HB_OT_METRICS_TAG_STRIKEOUT_OFFSET, "Strikeout Offset", row++);
|
||||
add_metrics_line (self, font, HB_OT_METRICS_TAG_STRIKEOUT_SIZE, "Underline Size", row++);
|
||||
add_metrics_line (self, font, HB_OT_METRICS_TAG_STRIKEOUT_OFFSET, "Underline Offset", row++);
|
||||
|
||||
gtk_grid_attach (self->info, make_title_label ("Style"), 0, row++, 2, 1);
|
||||
|
||||
add_style_line (self, font, HB_STYLE_TAG_ITALIC, "Italic", row++);
|
||||
add_style_line (self, font, HB_STYLE_TAG_OPTICAL_SIZE, "Optical Size", row++);
|
||||
add_style_line (self, font, HB_STYLE_TAG_SLANT_ANGLE, "Slant Angle", row++);
|
||||
add_style_line (self, font, HB_STYLE_TAG_WIDTH, "Width", row++);
|
||||
add_style_line (self, font, HB_STYLE_TAG_WEIGHT, "Weight", row++);
|
||||
|
||||
gtk_grid_attach (self->info, make_title_label ("Miscellaneous"), 0, row++, 2, 1);
|
||||
|
||||
count = hb_face_get_glyph_count (face);
|
||||
g_snprintf (buf, sizeof (buf), "%d", count);
|
||||
add_misc_line (self, "Glyph Count", buf, row++);
|
||||
|
||||
if (hb_ot_var_get_axis_count (face) > 0)
|
||||
{
|
||||
s = g_string_new ("");
|
||||
hb_ot_var_axis_info_t *axes;
|
||||
|
||||
axes = g_newa (hb_ot_var_axis_info_t, hb_ot_var_get_axis_count (face));
|
||||
count = hb_ot_var_get_axis_count (face);
|
||||
hb_ot_var_get_axis_infos (face, 0, &count, axes);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
char name[256];
|
||||
unsigned int len;
|
||||
|
||||
len = sizeof (buf);
|
||||
hb_ot_name_get_utf8 (face, axes[i].name_id, HB_LANGUAGE_INVALID, &len, name);
|
||||
if (s->len > 0)
|
||||
g_string_append (s, ", ");
|
||||
g_string_append (s, name);
|
||||
}
|
||||
add_misc_line (self, "Axes", s->str, row++);
|
||||
g_string_free (s, TRUE);
|
||||
}
|
||||
|
||||
if (hb_ot_var_get_named_instance_count (face) > 0)
|
||||
{
|
||||
s = g_string_new ("");
|
||||
for (int i = 0; i < hb_ot_var_get_named_instance_count (face); i++)
|
||||
{
|
||||
hb_ot_name_id_t name_id;
|
||||
char name[256];
|
||||
unsigned int len;
|
||||
|
||||
name_id = hb_ot_var_named_instance_get_subfamily_name_id (face, i);
|
||||
len = sizeof (buf);
|
||||
hb_ot_name_get_utf8 (face, name_id, HB_LANGUAGE_INVALID, &len, name);
|
||||
if (s->len > 0)
|
||||
g_string_append (s, ", ");
|
||||
g_string_append (s, name);
|
||||
}
|
||||
add_misc_line (self, "Named Instances", s->str, row++);
|
||||
g_string_free (s, TRUE);
|
||||
}
|
||||
|
||||
s = g_string_new ("");
|
||||
count = hb_face_get_table_tags (face, 0, NULL, NULL);
|
||||
tables = g_newa (hb_tag_t, count);
|
||||
hb_face_get_table_tags (face, 0, &count, tables);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
memset (buf, 0, sizeof (buf));
|
||||
hb_tag_to_string (tables[i], buf);
|
||||
if (s->len > 0)
|
||||
g_string_append (s, ", ");
|
||||
g_string_append (s, buf);
|
||||
}
|
||||
add_misc_line (self, "Tables", s->str, row++);
|
||||
g_string_free (s, TRUE);
|
||||
|
||||
s = g_string_new ("");
|
||||
if (hb_ot_color_has_palettes (face))
|
||||
g_string_append_printf (s, "%s", "Palettes");
|
||||
if (hb_ot_color_has_layers (face))
|
||||
g_string_append_printf (s, "%s%s", s->len > 0 ? ", " : "", "Layers");
|
||||
if (hb_ot_color_has_svg (face))
|
||||
g_string_append_printf (s, "%s%s", s->len > 0 ? ", " : "", "SVG");
|
||||
if (hb_ot_color_has_png (face))
|
||||
g_string_append_printf (s, "%s%s", s->len > 0 ? ", " : "", "PNG");
|
||||
if (s->len > 0)
|
||||
add_misc_line (self, "Color", s->str, row++);
|
||||
g_string_free (s, TRUE);
|
||||
|
||||
hb_font_destroy (font);
|
||||
}
|
||||
|
||||
static void
|
||||
info_view_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
InfoView *self = INFO_VIEW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FONT_MAP:
|
||||
g_set_object (&self->font_map, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_FONT_DESC:
|
||||
pango2_font_description_free (self->font_desc);
|
||||
self->font_desc = pango2_font_description_copy (g_value_get_boxed (value));
|
||||
break;
|
||||
|
||||
case PROP_SIZE:
|
||||
self->size = g_value_get_float (value);
|
||||
break;
|
||||
|
||||
case PROP_VARIATIONS:
|
||||
g_free (self->variations);
|
||||
self->variations = g_strdup (g_value_get_string (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
|
||||
update_info (self);
|
||||
}
|
||||
|
||||
static void
|
||||
info_view_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
InfoView *self = INFO_VIEW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FONT_MAP:
|
||||
g_value_set_object (value, self->font_map);
|
||||
break;
|
||||
|
||||
case PROP_FONT_DESC:
|
||||
g_value_set_boxed (value, self->font_desc);
|
||||
break;
|
||||
|
||||
case PROP_SIZE:
|
||||
g_value_set_float (value, self->size);
|
||||
break;
|
||||
|
||||
case PROP_VARIATIONS:
|
||||
g_value_set_string (value, self->variations);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
info_view_class_init (InfoViewClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->dispose = info_view_dispose;
|
||||
object_class->finalize = info_view_finalize;
|
||||
object_class->get_property = info_view_get_property;
|
||||
object_class->set_property = info_view_set_property;
|
||||
|
||||
properties[PROP_FONT_MAP] =
|
||||
g_param_spec_object ("font-map", "", "",
|
||||
PANGO2_TYPE_FONT_MAP,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_FONT_DESC] =
|
||||
g_param_spec_boxed ("font-desc", "", "",
|
||||
PANGO2_TYPE_FONT_DESCRIPTION,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_SIZE] =
|
||||
g_param_spec_float ("size", "", "",
|
||||
0., 100., 12.,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_VARIATIONS] =
|
||||
g_param_spec_string ("variations", "", "",
|
||||
"",
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/fontexplorer/infoview.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), InfoView, info);
|
||||
|
||||
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "infoview");
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define INFO_VIEW_TYPE (info_view_get_type ())
|
||||
#define INFO_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INFO_VIEW_TYPE, InfoView))
|
||||
|
||||
|
||||
typedef struct _InfoView InfoView;
|
||||
typedef struct _InfoViewClass InfoViewClass;
|
||||
|
||||
|
||||
GType info_view_get_type (void);
|
||||
@@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="InfoView" parent="GtkWidget">
|
||||
<style>
|
||||
<class name="view"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="vscrollbar-policy">automatic</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkGrid" id="info">
|
||||
<style>
|
||||
<class name="content"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -1,334 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <hb-ot.h>
|
||||
|
||||
#include "language-names.h"
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#else
|
||||
#ifndef ISO_CODES_PREFIX
|
||||
#define ISO_CODES_PREFIX "/usr"
|
||||
#endif
|
||||
|
||||
#define ISO_CODES_DATADIR ISO_CODES_PREFIX "/share/xml/iso-codes"
|
||||
#define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX "/share/locale"
|
||||
#endif
|
||||
|
||||
static GHashTable *language_map;
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
/* if we are using native Windows use native Windows API for language names */
|
||||
static BOOL CALLBACK
|
||||
get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param)
|
||||
{
|
||||
wchar_t *langname_w = NULL;
|
||||
wchar_t locale_abbrev_w[9];
|
||||
gchar *langname, *locale_abbrev, *locale, *p;
|
||||
gint i;
|
||||
const LCTYPE iso639_lctypes[] = { LOCALE_SISO639LANGNAME, LOCALE_SISO639LANGNAME2 };
|
||||
GHashTable *ht_scripts_langs = (GHashTable *) param;
|
||||
Pango2Language *lang;
|
||||
|
||||
gint langname_size, locale_abbrev_size;
|
||||
langname_size = GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, 0);
|
||||
if (langname_size == 0)
|
||||
return FALSE;
|
||||
|
||||
langname_w = g_new0 (wchar_t, langname_size);
|
||||
|
||||
if (langname_size == 0)
|
||||
return FALSE;
|
||||
|
||||
GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, langname_size);
|
||||
langname = g_utf16_to_utf8 (langname_w, -1, NULL, NULL, NULL);
|
||||
locale = g_utf16_to_utf8 (locale_w, -1, NULL, NULL, NULL);
|
||||
p = strchr (locale, '-');
|
||||
lang = pango2_language_from_string (locale);
|
||||
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
|
||||
g_hash_table_insert (ht_scripts_langs, lang, langname);
|
||||
|
||||
/*
|
||||
* Track 3+-letter ISO639-2/3 language codes as well (these have a max length of 9 including terminating NUL)
|
||||
* ISO639-2: iso639_lctypes[0] = LOCALE_SISO639LANGNAME
|
||||
* ISO639-3: iso639_lctypes[1] = LOCALE_SISO639LANGNAME2
|
||||
*/
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
locale_abbrev_size = GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, 0);
|
||||
if (locale_abbrev_size > 0)
|
||||
{
|
||||
GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, locale_abbrev_size);
|
||||
|
||||
locale_abbrev = g_utf16_to_utf8 (locale_abbrev_w, -1, NULL, NULL, NULL);
|
||||
lang = pango2_language_from_string (locale_abbrev);
|
||||
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
|
||||
g_hash_table_insert (ht_scripts_langs, lang, langname);
|
||||
|
||||
g_free (locale_abbrev);
|
||||
}
|
||||
}
|
||||
|
||||
g_free (locale);
|
||||
g_free (langname_w);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#else /* non-Windows */
|
||||
|
||||
static char *
|
||||
get_first_item_in_semicolon_list (const char *list)
|
||||
{
|
||||
char **items;
|
||||
char *item;
|
||||
|
||||
items = g_strsplit (list, "; ", 2);
|
||||
|
||||
item = g_strdup (items[0]);
|
||||
g_strfreev (items);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
static char *
|
||||
capitalize_utf8_string (const char *str)
|
||||
{
|
||||
char first[8] = { 0 };
|
||||
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
g_unichar_to_utf8 (g_unichar_totitle (g_utf8_get_char (str)), first);
|
||||
|
||||
return g_strconcat (first, g_utf8_offset_to_pointer (str, 1), NULL);
|
||||
}
|
||||
|
||||
static char *
|
||||
get_display_name (const char *language)
|
||||
{
|
||||
const char *translated;
|
||||
char *tmp;
|
||||
char *name;
|
||||
|
||||
translated = dgettext ("iso_639", language);
|
||||
|
||||
tmp = get_first_item_in_semicolon_list (translated);
|
||||
name = capitalize_utf8_string (tmp);
|
||||
g_free (tmp);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
static void
|
||||
languages_parse_start_tag (GMarkupParseContext *ctx,
|
||||
const char *element_name,
|
||||
const char **attr_names,
|
||||
const char **attr_values,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
const char *ccode_longB;
|
||||
const char *ccode_longT;
|
||||
const char *ccode;
|
||||
const char *ccode_id;
|
||||
const char *lang_name;
|
||||
char *display_name;
|
||||
const char *long_names[] = {
|
||||
"Dogri",
|
||||
"Greek, Modern",
|
||||
"Interlingua",
|
||||
"Konkani",
|
||||
"Tonga",
|
||||
"Turkish, Ottoman",
|
||||
};
|
||||
int i;
|
||||
|
||||
if (!(g_str_equal (element_name, "iso_639_entry") ||
|
||||
g_str_equal (element_name, "iso_639_3_entry")) ||
|
||||
attr_names == NULL ||
|
||||
attr_values == NULL)
|
||||
return;
|
||||
|
||||
ccode = NULL;
|
||||
ccode_longB = NULL;
|
||||
ccode_longT = NULL;
|
||||
ccode_id = NULL;
|
||||
lang_name = NULL;
|
||||
|
||||
while (*attr_names && *attr_values)
|
||||
{
|
||||
if (g_str_equal (*attr_names, "iso_639_1_code"))
|
||||
{
|
||||
if (**attr_values)
|
||||
{
|
||||
if (strlen (*attr_values) != 2)
|
||||
return;
|
||||
ccode = *attr_values;
|
||||
}
|
||||
}
|
||||
else if (g_str_equal (*attr_names, "iso_639_2B_code"))
|
||||
{
|
||||
if (**attr_values)
|
||||
{
|
||||
if (strlen (*attr_values) != 3)
|
||||
return;
|
||||
ccode_longB = *attr_values;
|
||||
}
|
||||
}
|
||||
else if (g_str_equal (*attr_names, "iso_639_2T_code"))
|
||||
{
|
||||
if (**attr_values)
|
||||
{
|
||||
if (strlen (*attr_values) != 3)
|
||||
return;
|
||||
ccode_longT = *attr_values;
|
||||
}
|
||||
}
|
||||
else if (g_str_equal (*attr_names, "id"))
|
||||
{
|
||||
if (**attr_values)
|
||||
{
|
||||
if (strlen (*attr_values) != 2 &&
|
||||
strlen (*attr_values) != 3)
|
||||
return;
|
||||
ccode_id = *attr_values;
|
||||
}
|
||||
}
|
||||
else if (g_str_equal (*attr_names, "name"))
|
||||
{
|
||||
lang_name = *attr_values;
|
||||
}
|
||||
|
||||
++attr_names;
|
||||
++attr_values;
|
||||
}
|
||||
|
||||
if (lang_name == NULL)
|
||||
return;
|
||||
|
||||
display_name = get_display_name (lang_name);
|
||||
|
||||
/* Fix up some egregious names */
|
||||
for (i = 0; i < G_N_ELEMENTS (long_names); i++)
|
||||
{
|
||||
if (g_str_has_prefix (display_name, long_names[i]))
|
||||
display_name[strlen (long_names[i])] = '\0';
|
||||
}
|
||||
|
||||
|
||||
if (ccode != NULL)
|
||||
g_hash_table_insert (language_map,
|
||||
pango2_language_from_string (ccode),
|
||||
g_strdup (display_name));
|
||||
|
||||
if (ccode_longB != NULL)
|
||||
g_hash_table_insert (language_map,
|
||||
pango2_language_from_string (ccode_longB),
|
||||
g_strdup (display_name));
|
||||
|
||||
if (ccode_longT != NULL)
|
||||
g_hash_table_insert (language_map,
|
||||
pango2_language_from_string (ccode_longT),
|
||||
g_strdup (display_name));
|
||||
|
||||
if (ccode_id != NULL)
|
||||
g_hash_table_insert (language_map,
|
||||
pango2_language_from_string (ccode_id),
|
||||
g_strdup (display_name));
|
||||
|
||||
g_free (display_name);
|
||||
}
|
||||
|
||||
static void
|
||||
languages_variant_init (const char *variant)
|
||||
{
|
||||
gboolean res;
|
||||
gsize buf_len;
|
||||
char *buf;
|
||||
char *filename;
|
||||
GError *error;
|
||||
|
||||
bindtextdomain (variant, ISO_CODES_LOCALESDIR);
|
||||
bind_textdomain_codeset (variant, "UTF-8");
|
||||
|
||||
error = NULL;
|
||||
filename = g_strconcat (ISO_CODES_DATADIR, "/", variant, ".xml", NULL);
|
||||
res = g_file_get_contents (filename, &buf, &buf_len, &error);
|
||||
if (res)
|
||||
{
|
||||
GMarkupParseContext *ctx = NULL;
|
||||
GMarkupParser parser = { languages_parse_start_tag, NULL, NULL, NULL, NULL };
|
||||
|
||||
ctx = g_markup_parse_context_new (&parser, 0, NULL, NULL);
|
||||
|
||||
res = g_markup_parse_context_parse (ctx, buf, buf_len, &error);
|
||||
g_free (ctx);
|
||||
|
||||
if (!res)
|
||||
{
|
||||
g_warning ("Failed to parse '%s': %s\n", filename, error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Failed to load '%s': %s\n", filename, error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_free (filename);
|
||||
g_free (buf);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
languages_init (void)
|
||||
{
|
||||
if (language_map)
|
||||
return;
|
||||
|
||||
language_map = g_hash_table_new_full (NULL, NULL, NULL, g_free);
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
g_return_if_fail (EnumSystemLocalesEx (&get_win32_all_locales_scripts, LOCALE_ALL, (LPARAM) language_map, NULL));
|
||||
#else
|
||||
languages_variant_init ("iso_639");
|
||||
languages_variant_init ("iso_639_3");
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *
|
||||
get_language_name (Pango2Language *language)
|
||||
{
|
||||
languages_init ();
|
||||
|
||||
return (const char *) g_hash_table_lookup (language_map, language);
|
||||
}
|
||||
|
||||
const char *
|
||||
get_language_name_for_tag (guint32 tag)
|
||||
{
|
||||
hb_language_t lang;
|
||||
const char *s;
|
||||
|
||||
lang = hb_ot_tag_to_language (tag);
|
||||
s = hb_language_to_string (lang);
|
||||
|
||||
return get_language_name (pango2_language_from_string (s));
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
#ifndef LANGUAGE_NAMES_H
|
||||
#define LANGUAGE_NAMES_H
|
||||
|
||||
#include <pango2/pango.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
const char * get_language_name (Pango2Language *language);
|
||||
const char * get_language_name_for_tag (guint32 tag);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
@@ -1,9 +0,0 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <fontexplorerapp.h>
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
return g_application_run (G_APPLICATION (font_explorer_app_new ()), argc, argv);
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
fontexplorer_sources = [
|
||||
'fontcolors.c',
|
||||
'fontcontrols.c',
|
||||
'fontexplorerapp.c',
|
||||
'fontexplorerwin.c',
|
||||
'fontfeatures.c',
|
||||
'fontvariations.c',
|
||||
'glyphitem.c',
|
||||
'glyphmodel.c',
|
||||
'glyphsview.c',
|
||||
'glyphview.c',
|
||||
'infoview.c',
|
||||
'language-names.c',
|
||||
'main.c',
|
||||
'plainview.c',
|
||||
'rangeedit.c',
|
||||
'samplechooser.c',
|
||||
'sampleeditor.c',
|
||||
'styleview.c',
|
||||
'waterfallview.c',
|
||||
]
|
||||
|
||||
fontexplorer_resources = gnome.compile_resources('fontexplorer_resources',
|
||||
'fontexplorer.gresource.xml',
|
||||
source_dir: '.',
|
||||
)
|
||||
|
||||
executable('gtk4-font-explorer',
|
||||
sources: [fontexplorer_sources, fontexplorer_resources],
|
||||
c_args: common_cflags,
|
||||
dependencies: [ libgtk_dep, demo_conf_h ],
|
||||
include_directories: confinc,
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true,
|
||||
)
|
||||
@@ -1,343 +0,0 @@
|
||||
#include "plainview.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <hb-ot.h>
|
||||
|
||||
#include "glyphitem.h"
|
||||
#include "glyphmodel.h"
|
||||
#include "glyphview.h"
|
||||
|
||||
enum {
|
||||
PROP_FONT_MAP = 1,
|
||||
PROP_FONT_DESC,
|
||||
PROP_SIZE,
|
||||
PROP_LETTERSPACING,
|
||||
PROP_LINE_HEIGHT,
|
||||
PROP_FOREGROUND,
|
||||
PROP_BACKGROUND,
|
||||
PROP_VARIATIONS,
|
||||
PROP_FEATURES,
|
||||
PROP_PALETTE,
|
||||
PROP_SAMPLE_TEXT,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
struct _PlainView
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
GtkLabel *content;
|
||||
GtkScrolledWindow *swin;
|
||||
|
||||
Pango2FontMap *font_map;
|
||||
Pango2FontDescription *font_desc;
|
||||
float size;
|
||||
char *variations;
|
||||
char *features;
|
||||
char *palette;
|
||||
GQuark palette_quark;
|
||||
int letterspacing;
|
||||
float line_height;
|
||||
GdkRGBA foreground;
|
||||
GdkRGBA background;
|
||||
GtkCssProvider *bg_provider;
|
||||
char *sample_text;
|
||||
};
|
||||
|
||||
struct _PlainViewClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(PlainView, plain_view, GTK_TYPE_WIDGET);
|
||||
|
||||
static void
|
||||
plain_view_init (PlainView *self)
|
||||
{
|
||||
self->font_map = g_object_ref (pango2_font_map_get_default ());
|
||||
self->font_desc = pango2_font_description_from_string ("sans 12");
|
||||
self->size = 12.;
|
||||
self->letterspacing = 0;
|
||||
self->line_height = 1.;
|
||||
self->variations = g_strdup ("");
|
||||
self->features = g_strdup ("");
|
||||
self->palette = g_strdup (PANGO2_COLOR_PALETTE_DEFAULT);
|
||||
self->palette_quark = g_quark_from_string (self->palette);
|
||||
self->foreground = (GdkRGBA){0., 0., 0., 1. };
|
||||
self->background = (GdkRGBA){1., 1., 1., 1. };
|
||||
self->sample_text = g_strdup ("Some sample text is better than other sample text");
|
||||
|
||||
gtk_widget_set_layout_manager (GTK_WIDGET (self),
|
||||
gtk_box_layout_new (GTK_ORIENTATION_VERTICAL));
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
self->bg_provider = gtk_css_provider_new ();
|
||||
gtk_style_context_add_provider (gtk_widget_get_style_context (GTK_WIDGET (self->content)),
|
||||
GTK_STYLE_PROVIDER (self->bg_provider), 800);
|
||||
}
|
||||
|
||||
static void
|
||||
plain_view_dispose (GObject *object)
|
||||
{
|
||||
gtk_widget_clear_template (GTK_WIDGET (object), PLAIN_VIEW_TYPE);
|
||||
|
||||
G_OBJECT_CLASS (plain_view_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
plain_view_finalize (GObject *object)
|
||||
{
|
||||
PlainView *self = PLAIN_VIEW (object);
|
||||
|
||||
g_clear_object (&self->font_map);
|
||||
pango2_font_description_free (self->font_desc);
|
||||
g_free (self->variations);
|
||||
g_free (self->features);
|
||||
g_free (self->palette);
|
||||
|
||||
G_OBJECT_CLASS (plain_view_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
update_view (PlainView *self)
|
||||
{
|
||||
Pango2FontDescription *desc;
|
||||
Pango2AttrList *attrs;
|
||||
char *fg, *bg, *css;
|
||||
|
||||
desc = pango2_font_description_copy_static (self->font_desc);
|
||||
pango2_font_description_set_size (desc, 12 * PANGO2_SCALE);
|
||||
pango2_font_description_set_variations (desc, self->variations);
|
||||
|
||||
attrs = pango2_attr_list_new ();
|
||||
pango2_attr_list_insert (attrs, pango2_attr_font_desc_new (desc));
|
||||
pango2_attr_list_insert (attrs, pango2_attr_size_new (self->size * PANGO2_SCALE));
|
||||
pango2_attr_list_insert (attrs, pango2_attr_letter_spacing_new (self->letterspacing));
|
||||
pango2_attr_list_insert (attrs, pango2_attr_line_height_new (self->line_height));
|
||||
pango2_attr_list_insert (attrs, pango2_attr_foreground_new (&(Pango2Color){65535 * self->foreground.red,
|
||||
65535 * self->foreground.green,
|
||||
65535 * self->foreground.blue,
|
||||
65535 * self->foreground.alpha}));
|
||||
pango2_attr_list_insert (attrs, pango2_attr_font_features_new (self->features));
|
||||
pango2_attr_list_insert (attrs, pango2_attr_palette_new (self->palette));
|
||||
|
||||
pango2_font_description_free (desc);
|
||||
|
||||
gtk_label_set_label (self->content, self->sample_text);
|
||||
gtk_label_set_attributes (self->content, attrs);
|
||||
|
||||
pango2_attr_list_unref (attrs);
|
||||
|
||||
fg = gdk_rgba_to_string (&self->foreground);
|
||||
bg = gdk_rgba_to_string (&self->background);
|
||||
css = g_strdup_printf (".content { caret-color: %s; background-color: %s; }", fg, bg);
|
||||
gtk_css_provider_load_from_data (self->bg_provider, css, strlen (css));
|
||||
g_free (css);
|
||||
g_free (fg);
|
||||
g_free (bg);
|
||||
}
|
||||
|
||||
static void
|
||||
plain_view_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
PlainView *self = PLAIN_VIEW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FONT_MAP:
|
||||
g_set_object (&self->font_map, g_value_get_object (value));
|
||||
gtk_widget_set_font_map (GTK_WIDGET (self->content), self->font_map);
|
||||
break;
|
||||
|
||||
case PROP_FONT_DESC:
|
||||
pango2_font_description_free (self->font_desc);
|
||||
self->font_desc = pango2_font_description_copy (g_value_get_boxed (value));
|
||||
break;
|
||||
|
||||
case PROP_SIZE:
|
||||
self->size = g_value_get_float (value);
|
||||
break;
|
||||
|
||||
case PROP_LETTERSPACING:
|
||||
self->letterspacing = g_value_get_int (value);
|
||||
break;
|
||||
|
||||
case PROP_LINE_HEIGHT:
|
||||
self->line_height = g_value_get_float (value);
|
||||
break;
|
||||
|
||||
case PROP_FOREGROUND:
|
||||
self->foreground = *(GdkRGBA *)g_value_get_boxed (value);
|
||||
break;
|
||||
|
||||
case PROP_BACKGROUND:
|
||||
self->background = *(GdkRGBA *)g_value_get_boxed (value);
|
||||
break;
|
||||
|
||||
case PROP_VARIATIONS:
|
||||
g_free (self->variations);
|
||||
self->variations = g_strdup (g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_FEATURES:
|
||||
g_free (self->features);
|
||||
self->features = g_strdup (g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_PALETTE:
|
||||
g_free (self->palette);
|
||||
self->palette = g_strdup (g_value_get_string (value));
|
||||
self->palette_quark = g_quark_from_string (self->palette);
|
||||
break;
|
||||
|
||||
case PROP_SAMPLE_TEXT:
|
||||
g_free (self->sample_text);
|
||||
self->sample_text = g_strdup (g_value_get_string (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
|
||||
update_view (self);
|
||||
}
|
||||
|
||||
static void
|
||||
plain_view_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
PlainView *self = PLAIN_VIEW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FONT_MAP:
|
||||
g_value_set_object (value, self->font_map);
|
||||
break;
|
||||
|
||||
case PROP_FONT_DESC:
|
||||
g_value_set_boxed (value, self->font_desc);
|
||||
break;
|
||||
|
||||
case PROP_SIZE:
|
||||
g_value_set_float (value, self->size);
|
||||
break;
|
||||
|
||||
case PROP_LETTERSPACING:
|
||||
g_value_set_int (value, self->letterspacing);
|
||||
break;
|
||||
|
||||
case PROP_LINE_HEIGHT:
|
||||
g_value_set_float (value, self->line_height);
|
||||
break;
|
||||
|
||||
case PROP_FOREGROUND:
|
||||
g_value_set_boxed (value, &self->foreground);
|
||||
break;
|
||||
|
||||
case PROP_BACKGROUND:
|
||||
g_value_set_boxed (value, &self->background);
|
||||
break;
|
||||
|
||||
case PROP_VARIATIONS:
|
||||
g_value_set_string (value, self->variations);
|
||||
break;
|
||||
|
||||
case PROP_FEATURES:
|
||||
g_value_set_string (value, self->features);
|
||||
break;
|
||||
|
||||
case PROP_PALETTE:
|
||||
g_value_set_string (value, self->palette);
|
||||
break;
|
||||
|
||||
case PROP_SAMPLE_TEXT:
|
||||
g_value_set_string (value, self->sample_text);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
plain_view_class_init (PlainViewClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->dispose = plain_view_dispose;
|
||||
object_class->finalize = plain_view_finalize;
|
||||
object_class->get_property = plain_view_get_property;
|
||||
object_class->set_property = plain_view_set_property;
|
||||
|
||||
properties[PROP_FONT_MAP] =
|
||||
g_param_spec_object ("font-map", "", "",
|
||||
PANGO2_TYPE_FONT_MAP,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_FONT_DESC] =
|
||||
g_param_spec_boxed ("font-desc", "", "",
|
||||
PANGO2_TYPE_FONT_DESCRIPTION,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_SIZE] =
|
||||
g_param_spec_float ("size", "", "",
|
||||
0., 100., 12.,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_LETTERSPACING] =
|
||||
g_param_spec_int ("letterspacing", "", "",
|
||||
-G_MAXINT, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_LINE_HEIGHT] =
|
||||
g_param_spec_float ("line-height", "", "",
|
||||
0., 100., 1.,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_FOREGROUND] =
|
||||
g_param_spec_boxed ("foreground", "", "",
|
||||
GDK_TYPE_RGBA,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_BACKGROUND] =
|
||||
g_param_spec_boxed ("background", "", "",
|
||||
GDK_TYPE_RGBA,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_VARIATIONS] =
|
||||
g_param_spec_string ("variations", "", "",
|
||||
"",
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_FEATURES] =
|
||||
g_param_spec_string ("features", "", "",
|
||||
"",
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_PALETTE] =
|
||||
g_param_spec_string ("palette", "", "",
|
||||
PANGO2_COLOR_PALETTE_DEFAULT,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_SAMPLE_TEXT] =
|
||||
g_param_spec_string ("sample-text", "", "",
|
||||
"",
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/fontexplorer/plainview.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PlainView, swin);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PlainView, content);
|
||||
|
||||
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "plainview");
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define PLAIN_VIEW_TYPE (plain_view_get_type ())
|
||||
#define PLAIN_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PLAIN_VIEW_TYPE, PlainView))
|
||||
|
||||
|
||||
typedef struct _PlainView PlainView;
|
||||
typedef struct _PlainViewClass PlainViewClass;
|
||||
|
||||
|
||||
GType plain_view_get_type (void);
|
||||
@@ -1,32 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="PlainView" parent="GtkWidget">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="swin">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="vscrollbar-policy">automatic</property>
|
||||
<style>
|
||||
<class name="view"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkLabel" id="content">
|
||||
<property name="label">Content</property>
|
||||
<property name="wrap">1</property>
|
||||
<property name="wrap-mode">word-char</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<property name="halign">fill</property>
|
||||
<property name="valign">fill</property>
|
||||
<style>
|
||||
<class name="content"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -1,174 +0,0 @@
|
||||
#include "rangeedit.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <hb-ot.h>
|
||||
|
||||
enum {
|
||||
PROP_ADJUSTMENT = 1,
|
||||
PROP_DEFAULT_VALUE,
|
||||
PROP_N_CHARS,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
struct _RangeEdit
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
GtkAdjustment *adjustment;
|
||||
GtkScale *scale;
|
||||
GtkEntry *entry;
|
||||
double default_value;
|
||||
int n_chars;
|
||||
};
|
||||
|
||||
struct _RangeEditClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (RangeEdit, range_edit, GTK_TYPE_WIDGET);
|
||||
|
||||
static void
|
||||
range_edit_init (RangeEdit *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
range_edit_dispose (GObject *object)
|
||||
{
|
||||
gtk_widget_clear_template (GTK_WIDGET (object), RANGE_EDIT_TYPE);
|
||||
|
||||
G_OBJECT_CLASS (range_edit_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
range_edit_get_property (GObject *object,
|
||||
unsigned int prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
RangeEdit *self = RANGE_EDIT (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ADJUSTMENT:
|
||||
g_value_set_object (value, self->adjustment);
|
||||
break;
|
||||
|
||||
case PROP_DEFAULT_VALUE:
|
||||
g_value_set_double (value, self->default_value);
|
||||
break;
|
||||
|
||||
case PROP_N_CHARS:
|
||||
g_value_set_int (value, self->n_chars);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
adjustment_changed (GtkAdjustment *adjustment,
|
||||
RangeEdit *self)
|
||||
{
|
||||
char *str;
|
||||
|
||||
str = g_strdup_printf ("%.1f", gtk_adjustment_get_value (adjustment));
|
||||
gtk_editable_set_text (GTK_EDITABLE (self->entry), str);
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
static void
|
||||
range_edit_set_property (GObject *object,
|
||||
unsigned int prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
RangeEdit *self = RANGE_EDIT (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ADJUSTMENT:
|
||||
g_set_object (&self->adjustment, g_value_get_object (value));
|
||||
g_signal_connect (self->adjustment, "value-changed", G_CALLBACK (adjustment_changed), self);
|
||||
adjustment_changed (self->adjustment, self);
|
||||
break;
|
||||
|
||||
case PROP_DEFAULT_VALUE:
|
||||
self->default_value = g_value_get_double (value);
|
||||
break;
|
||||
|
||||
case PROP_N_CHARS:
|
||||
self->n_chars = g_value_get_int (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
range_edit_constructed (GObject *object)
|
||||
{
|
||||
RangeEdit *self = RANGE_EDIT (object);
|
||||
|
||||
gtk_scale_add_mark (self->scale, self->default_value, GTK_POS_TOP, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
entry_activated (GtkEntry *entry,
|
||||
RangeEdit *self)
|
||||
{
|
||||
double value;
|
||||
char *err = NULL;
|
||||
|
||||
value = g_strtod (gtk_editable_get_text (GTK_EDITABLE (entry)), &err);
|
||||
if (err != NULL)
|
||||
gtk_adjustment_set_value (self->adjustment, value);
|
||||
}
|
||||
|
||||
static void
|
||||
range_edit_class_init (RangeEditClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->dispose = range_edit_dispose;
|
||||
object_class->get_property = range_edit_get_property;
|
||||
object_class->set_property = range_edit_set_property;
|
||||
object_class->constructed = range_edit_constructed;
|
||||
|
||||
properties[PROP_ADJUSTMENT] =
|
||||
g_param_spec_object ("adjustment", "", "",
|
||||
GTK_TYPE_ADJUSTMENT,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
properties[PROP_DEFAULT_VALUE] =
|
||||
g_param_spec_double ("default-value", "", "",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0.,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
properties[PROP_N_CHARS] =
|
||||
g_param_spec_int ("n-chars", "", "",
|
||||
0, G_MAXINT, 10,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/fontexplorer/rangeedit.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), RangeEdit, scale);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), RangeEdit, entry);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), entry_activated);
|
||||
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "rangeedit");
|
||||
}
|
||||
|
||||
RangeEdit *
|
||||
range_edit_new (void)
|
||||
{
|
||||
return g_object_new (RANGE_EDIT_TYPE, NULL);
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define RANGE_EDIT_TYPE (range_edit_get_type ())
|
||||
#define RANGE_EDIT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RANGE_EDIT_TYPE, RangeEdit))
|
||||
|
||||
|
||||
typedef struct _RangeEdit RangeEdit;
|
||||
typedef struct _RangeEditClass RangeEditClass;
|
||||
|
||||
|
||||
GType range_edit_get_type (void);
|
||||
RangeEdit * range_edit_new (void);
|
||||
@@ -1,24 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="RangeEdit" parent="GtkWidget">
|
||||
<property name="layout-manager">
|
||||
<object class="GtkBoxLayout">
|
||||
<property name="spacing">10</property>
|
||||
</object>
|
||||
</property>
|
||||
<child>
|
||||
<object class="GtkScale" id="scale">
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="adjustment" bind-source="RangeEdit" bind-flags="sync-create"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry">
|
||||
<property name="width-chars" bind-source="RangeEdit" bind-property="n-chars" bind-flags="sync-create"/>
|
||||
<property name="max-width-chars" bind-source="RangeEdit" bind-property="n-chars" bind-flags="sync-create"/>
|
||||
<signal name="activate" handler="entry_activated"/>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -1,163 +0,0 @@
|
||||
#include "samplechooser.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <hb-ot.h>
|
||||
|
||||
enum {
|
||||
PROP_SAMPLE_TEXT = 1,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
struct _SampleChooser
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
int sample;
|
||||
const char *sample_text;
|
||||
};
|
||||
|
||||
struct _SampleChooserClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(SampleChooser, sample_chooser, GTK_TYPE_WIDGET);
|
||||
|
||||
static const char *pangrams[] = {
|
||||
"The quick brown fox jumps over the lazy dog.",
|
||||
"Waltz, bad nymph, for quick jigs vex.",
|
||||
"Quick zephyrs blow, vexing daft Jim.",
|
||||
"Crazy Fredrick bought many very exquisite opal jewels.",
|
||||
"Jaded zombies acted quaintly but kept driving their oxen forward.",
|
||||
};
|
||||
|
||||
static const char *paragraphs[] = {
|
||||
"Grumpy wizards make toxic brew for the evil Queen and Jack. A quick movement of the enemy will jeopardize six gunboats. The job of waxing linoleum frequently peeves chintzy kids. My girl wove six dozen plaid jackets before she quit. Twelve ziggurats quickly jumped a finch box.",
|
||||
" Разъяренный чтец эгоистично бьёт пятью жердями шустрого фехтовальщика. Наш банк вчера же выплатил Ф.Я. Эйхгольду комиссию за ценные вещи. Эх, чужак, общий съём цен шляп (юфть) – вдрызг! В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!",
|
||||
"Τάχιστη αλώπηξ βαφής ψημένη γη, δρασκελίζει υπέρ νωθρού κυνός",
|
||||
};
|
||||
|
||||
static const char *alphabets[] = {
|
||||
"abcdefghijklmnopqrstuvwxyz",
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
||||
"0123456789",
|
||||
"!@#$%^&*()?",
|
||||
};
|
||||
|
||||
static const char *titles[] = {
|
||||
"From My Cold Dead Hands",
|
||||
"From Afar Upon the Back of a Tiger",
|
||||
"Spontaneous Apple Creation",
|
||||
"Big Bizness (Screwed & Chopped)",
|
||||
"Pizza Shop Extended",
|
||||
"Good News & Bad News",
|
||||
};
|
||||
|
||||
static void
|
||||
next_pangram (GtkButton *button,
|
||||
SampleChooser *self)
|
||||
{
|
||||
self->sample++;
|
||||
self->sample_text = pangrams[self->sample % G_N_ELEMENTS (pangrams)];
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SAMPLE_TEXT]);
|
||||
}
|
||||
|
||||
static void
|
||||
next_paragraph (GtkButton *button,
|
||||
SampleChooser *self)
|
||||
{
|
||||
self->sample++;
|
||||
self->sample_text = paragraphs[self->sample % G_N_ELEMENTS (paragraphs)];
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SAMPLE_TEXT]);
|
||||
}
|
||||
|
||||
static void
|
||||
next_alphabet (GtkButton *button,
|
||||
SampleChooser *self)
|
||||
{
|
||||
self->sample++;
|
||||
self->sample_text = alphabets[self->sample % G_N_ELEMENTS (alphabets)];
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SAMPLE_TEXT]);
|
||||
}
|
||||
|
||||
static void
|
||||
next_title (GtkButton *button,
|
||||
SampleChooser *self)
|
||||
{
|
||||
self->sample++;
|
||||
self->sample_text = titles[self->sample % G_N_ELEMENTS (titles)];
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SAMPLE_TEXT]);
|
||||
}
|
||||
|
||||
static void
|
||||
sample_chooser_init (SampleChooser *self)
|
||||
{
|
||||
self->sample_text = "Boring sample text";
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
sample_chooser_dispose (GObject *object)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
gtk_widget_clear_template (GTK_WIDGET (object), SAMPLE_CHOOSER_TYPE);
|
||||
|
||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (object))) != NULL)
|
||||
gtk_widget_unparent (child);
|
||||
|
||||
G_OBJECT_CLASS (sample_chooser_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
sample_chooser_get_property (GObject *object,
|
||||
unsigned int prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
SampleChooser *self = SAMPLE_CHOOSER (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SAMPLE_TEXT:
|
||||
g_value_set_string (value, self->sample_text);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sample_chooser_class_init (SampleChooserClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->dispose = sample_chooser_dispose;
|
||||
object_class->get_property = sample_chooser_get_property;
|
||||
|
||||
properties[PROP_SAMPLE_TEXT] =
|
||||
g_param_spec_string ("sample-text", "", "",
|
||||
"",
|
||||
G_PARAM_READABLE);
|
||||
|
||||
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/fontexplorer/samplechooser.ui");
|
||||
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), next_pangram);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), next_paragraph);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), next_alphabet);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), next_title);
|
||||
|
||||
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "samplechooser");
|
||||
}
|
||||
|
||||
SampleChooser *
|
||||
sample_chooser_new (void)
|
||||
{
|
||||
return g_object_new (SAMPLE_CHOOSER_TYPE, NULL);
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define SAMPLE_CHOOSER_TYPE (sample_chooser_get_type ())
|
||||
#define SAMPLE_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SAMPLE_CHOOSER_TYPE, SampleChooser))
|
||||
|
||||
|
||||
typedef struct _SampleChooser SampleChooser;
|
||||
typedef struct _SampleChooserClass SampleChooserClass;
|
||||
|
||||
|
||||
GType sample_chooser_get_type (void);
|
||||
SampleChooser * sample_chooser_new (void);
|
||||
@@ -1,46 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="SampleChooser" parent="GtkWidget">
|
||||
<property name="layout-manager"><object class="GtkGridLayout"/></property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">Pangram</property>
|
||||
<signal name="clicked" handler="next_pangram"/>
|
||||
<layout>
|
||||
<property name="row">0</property>
|
||||
<property name="column">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">Paragraph</property>
|
||||
<signal name="clicked" handler="next_paragraph"/>
|
||||
<layout>
|
||||
<property name="row">0</property>
|
||||
<property name="column">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">Alphabet</property>
|
||||
<signal name="clicked" handler="next_alphabet"/>
|
||||
<layout>
|
||||
<property name="row">1</property>
|
||||
<property name="column">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">Title</property>
|
||||
<signal name="clicked" handler="next_title"/>
|
||||
<layout>
|
||||
<property name="row">1</property>
|
||||
<property name="column">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -1,162 +0,0 @@
|
||||
#include "sampleeditor.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
enum {
|
||||
PROP_SAMPLE_TEXT = 1,
|
||||
PROP_EDITING,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
struct _SampleEditor
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
GtkTextView *edit;
|
||||
char *sample_text;
|
||||
gboolean editing;
|
||||
};
|
||||
|
||||
struct _SampleEditorClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(SampleEditor, sample_editor, GTK_TYPE_WIDGET);
|
||||
|
||||
static void
|
||||
sample_editor_init (SampleEditor *self)
|
||||
{
|
||||
self->sample_text = g_strdup ("Some sample text is better than other sample text");
|
||||
self->editing = FALSE;
|
||||
|
||||
gtk_widget_set_layout_manager (GTK_WIDGET (self),
|
||||
gtk_box_layout_new (GTK_ORIENTATION_VERTICAL));
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
sample_editor_dispose (GObject *object)
|
||||
{
|
||||
gtk_widget_clear_template (GTK_WIDGET (object), SAMPLE_EDITOR_TYPE);
|
||||
|
||||
G_OBJECT_CLASS (sample_editor_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
sample_editor_finalize (GObject *object)
|
||||
{
|
||||
SampleEditor *self = SAMPLE_EDITOR (object);
|
||||
|
||||
g_free (self->sample_text);
|
||||
|
||||
G_OBJECT_CLASS (sample_editor_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
update_editing (SampleEditor *self,
|
||||
gboolean editing)
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
|
||||
if (self->editing == editing)
|
||||
return;
|
||||
|
||||
self->editing = editing;
|
||||
|
||||
buffer = gtk_text_view_get_buffer (self->edit);
|
||||
|
||||
if (self->editing)
|
||||
{
|
||||
gtk_text_buffer_set_text (buffer, self->sample_text, -1);
|
||||
gtk_widget_grab_focus (GTK_WIDGET (self->edit));
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkTextIter start, end;
|
||||
|
||||
g_free (self->sample_text);
|
||||
gtk_text_buffer_get_bounds (buffer, &start, &end);
|
||||
self->sample_text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SAMPLE_TEXT]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sample_editor_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
SampleEditor *self = SAMPLE_EDITOR (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SAMPLE_TEXT:
|
||||
g_free (self->sample_text);
|
||||
self->sample_text = g_strdup (g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_EDITING:
|
||||
update_editing (self, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sample_editor_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
SampleEditor *self = SAMPLE_EDITOR (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SAMPLE_TEXT:
|
||||
g_value_set_string (value, self->sample_text);
|
||||
break;
|
||||
|
||||
case PROP_EDITING:
|
||||
g_value_set_boolean (value, self->editing);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sample_editor_class_init (SampleEditorClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->dispose = sample_editor_dispose;
|
||||
object_class->finalize = sample_editor_finalize;
|
||||
object_class->get_property = sample_editor_get_property;
|
||||
object_class->set_property = sample_editor_set_property;
|
||||
|
||||
properties[PROP_SAMPLE_TEXT] =
|
||||
g_param_spec_string ("sample-text", "", "",
|
||||
"",
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_EDITING] =
|
||||
g_param_spec_boolean ("editing", "", "",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/fontexplorer/sampleeditor.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), SampleEditor, edit);
|
||||
|
||||
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "sampleeditor");
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define SAMPLE_EDITOR_TYPE (sample_editor_get_type ())
|
||||
#define SAMPLE_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SAMPLE_EDITOR_TYPE, SampleEditor))
|
||||
|
||||
|
||||
typedef struct _SampleEditor SampleEditor;
|
||||
typedef struct _SampleEditorClass SampleEditorClass;
|
||||
|
||||
|
||||
GType sample_editor_get_type (void);
|
||||
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="SampleEditor" parent="GtkWidget">
|
||||
<style>
|
||||
<class name="view"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="vscrollbar-policy">automatic</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkTextView" id="edit">
|
||||
<property name="wrap-mode">word-char</property>
|
||||
<property name="left-margin">20</property>
|
||||
<property name="right-margin">20</property>
|
||||
<property name="top-margin">20</property>
|
||||
<property name="bottom-margin">20</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -1,506 +0,0 @@
|
||||
#include "styleview.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <hb-ot.h>
|
||||
|
||||
#include "glyphitem.h"
|
||||
#include "glyphmodel.h"
|
||||
#include "glyphview.h"
|
||||
|
||||
enum {
|
||||
PROP_FONT_MAP = 1,
|
||||
PROP_FONT_DESC,
|
||||
PROP_SIZE,
|
||||
PROP_LETTERSPACING,
|
||||
PROP_LINE_HEIGHT,
|
||||
PROP_FOREGROUND,
|
||||
PROP_BACKGROUND,
|
||||
PROP_VARIATIONS,
|
||||
PROP_FEATURES,
|
||||
PROP_PALETTE,
|
||||
PROP_SAMPLE_TEXT,
|
||||
PROP_HAS_STYLES,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
struct _StyleView
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
GtkLabel *content;
|
||||
GtkScrolledWindow *swin;
|
||||
|
||||
Pango2FontMap *font_map;
|
||||
Pango2FontDescription *font_desc;
|
||||
float size;
|
||||
char *variations;
|
||||
char *features;
|
||||
char *palette;
|
||||
GQuark palette_quark;
|
||||
int letterspacing;
|
||||
float line_height;
|
||||
GdkRGBA foreground;
|
||||
GdkRGBA background;
|
||||
GtkCssProvider *bg_provider;
|
||||
char *sample_text;
|
||||
gboolean has_styles;
|
||||
};
|
||||
|
||||
struct _StyleViewClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(StyleView, style_view, GTK_TYPE_WIDGET);
|
||||
|
||||
static void
|
||||
style_view_init (StyleView *self)
|
||||
{
|
||||
self->font_map = g_object_ref (pango2_font_map_get_default ());
|
||||
self->font_desc = pango2_font_description_from_string ("sans 12");
|
||||
self->size = 12.;
|
||||
self->letterspacing = 0;
|
||||
self->line_height = 1.;
|
||||
self->variations = g_strdup ("");
|
||||
self->features = g_strdup ("");
|
||||
self->palette = g_strdup (PANGO2_COLOR_PALETTE_DEFAULT);
|
||||
self->palette_quark = g_quark_from_string (self->palette);
|
||||
self->foreground = (GdkRGBA){0., 0., 0., 1. };
|
||||
self->background = (GdkRGBA){1., 1., 1., 1. };
|
||||
self->sample_text = g_strdup ("Some sample text is better than other sample text");
|
||||
self->has_styles = FALSE;
|
||||
|
||||
gtk_widget_set_layout_manager (GTK_WIDGET (self),
|
||||
gtk_box_layout_new (GTK_ORIENTATION_VERTICAL));
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
self->bg_provider = gtk_css_provider_new ();
|
||||
gtk_style_context_add_provider (gtk_widget_get_style_context (GTK_WIDGET (self->content)),
|
||||
GTK_STYLE_PROVIDER (self->bg_provider), 800);
|
||||
}
|
||||
|
||||
static void
|
||||
style_view_dispose (GObject *object)
|
||||
{
|
||||
gtk_widget_clear_template (GTK_WIDGET (object), STYLE_VIEW_TYPE);
|
||||
|
||||
G_OBJECT_CLASS (style_view_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
style_view_finalize (GObject *object)
|
||||
{
|
||||
StyleView *self = STYLE_VIEW (object);
|
||||
|
||||
g_clear_object (&self->font_map);
|
||||
pango2_font_description_free (self->font_desc);
|
||||
g_free (self->variations);
|
||||
g_free (self->features);
|
||||
g_free (self->palette);
|
||||
|
||||
G_OBJECT_CLASS (style_view_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static Pango2Font *
|
||||
get_font (StyleView *self)
|
||||
{
|
||||
Pango2Context *context;
|
||||
Pango2FontDescription *desc;
|
||||
Pango2Font *font;
|
||||
|
||||
context = pango2_context_new_with_font_map (self->font_map);
|
||||
desc = pango2_font_description_copy_static (self->font_desc);
|
||||
pango2_font_description_set_variations (desc, self->variations);
|
||||
pango2_font_description_set_size (desc, self->size * PANGO2_SCALE);
|
||||
font = pango2_context_load_font (context, desc);
|
||||
pango2_font_description_free (desc);
|
||||
g_object_unref (context);
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
static void
|
||||
update_has_styles (StyleView *self)
|
||||
{
|
||||
Pango2Font *font = get_font (self);
|
||||
hb_face_t *hb_face = hb_font_get_face (pango2_font_get_hb_font (font));
|
||||
gboolean has_styles;
|
||||
|
||||
has_styles = hb_ot_var_get_named_instance_count (hb_face) > 0;
|
||||
g_object_unref (font);
|
||||
|
||||
if (self->has_styles == has_styles)
|
||||
return;
|
||||
|
||||
self->has_styles = has_styles;
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_HAS_STYLES]);
|
||||
}
|
||||
|
||||
static int
|
||||
measure_names (Pango2Context *context,
|
||||
hb_face_t *hb_face)
|
||||
{
|
||||
Pango2Layout *layout;
|
||||
Pango2FontDescription *desc;
|
||||
GString *str;
|
||||
int width, height;
|
||||
|
||||
layout = pango2_layout_new (context);
|
||||
|
||||
desc = pango2_font_description_from_string ("Cantarell Regular 12");
|
||||
pango2_layout_set_font_description (layout, desc);
|
||||
pango2_font_description_free (desc);
|
||||
|
||||
str = g_string_new ("");
|
||||
|
||||
for (int i = 0; i < hb_ot_var_get_named_instance_count (hb_face); i++)
|
||||
{
|
||||
hb_ot_name_id_t name_id;
|
||||
char name[20];
|
||||
unsigned int name_len = 20;
|
||||
|
||||
name_id = hb_ot_var_named_instance_get_subfamily_name_id (hb_face, i);
|
||||
hb_ot_name_get_utf8 (hb_face, name_id, HB_LANGUAGE_INVALID, &name_len, name);
|
||||
g_string_append_printf (str, " %s\n", name);
|
||||
}
|
||||
|
||||
pango2_layout_set_text (layout, str->str, -1);
|
||||
pango2_lines_get_size (pango2_layout_get_lines (layout), &width, &height);
|
||||
|
||||
g_string_free (str, TRUE);
|
||||
|
||||
g_object_unref (layout);
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
static void
|
||||
update_view (StyleView *self)
|
||||
{
|
||||
Pango2FontDescription *desc;
|
||||
Pango2AttrList *attrs;
|
||||
char *fg, *bg, *css;
|
||||
GString *str;
|
||||
int start, end, text_len;
|
||||
Pango2Font *font = get_font (self);
|
||||
hb_face_t *hb_face = hb_font_get_face (pango2_font_get_hb_font (font));
|
||||
unsigned int n_axes;
|
||||
float *coords = NULL;
|
||||
hb_ot_var_axis_info_t *axes;
|
||||
Pango2FontDescription *label_desc;
|
||||
Pango2TabArray *tabs;
|
||||
int width;
|
||||
|
||||
desc = pango2_font_description_copy_static (self->font_desc);
|
||||
pango2_font_description_set_variations (desc, self->variations);
|
||||
pango2_font_description_set_size (desc, self->size * PANGO2_SCALE);
|
||||
|
||||
attrs = pango2_attr_list_new ();
|
||||
pango2_attr_list_insert (attrs, pango2_attr_font_desc_new (desc));
|
||||
pango2_attr_list_insert (attrs, pango2_attr_letter_spacing_new (self->letterspacing));
|
||||
pango2_attr_list_insert (attrs, pango2_attr_line_height_new (self->line_height));
|
||||
pango2_attr_list_insert (attrs, pango2_attr_foreground_new (&(Pango2Color){65535 * self->foreground.red,
|
||||
65535 * self->foreground.green,
|
||||
65535 * self->foreground.blue,
|
||||
65535 * self->foreground.alpha}));
|
||||
pango2_attr_list_insert (attrs, pango2_attr_font_features_new (self->features));
|
||||
pango2_attr_list_insert (attrs, pango2_attr_palette_new (self->palette));
|
||||
|
||||
str = g_string_new ("");
|
||||
start = 0;
|
||||
text_len = strlen (self->sample_text);
|
||||
|
||||
n_axes = hb_ot_var_get_axis_count (hb_face);
|
||||
axes = g_newa (hb_ot_var_axis_info_t, n_axes);
|
||||
hb_ot_var_get_axis_infos (hb_face, 0, &n_axes, axes);
|
||||
coords = g_newa (float, n_axes);
|
||||
|
||||
label_desc = pango2_font_description_from_string ("Cantarell Regular 12");
|
||||
|
||||
width = measure_names (gtk_widget_get_pango_context (GTK_WIDGET (self->content)), hb_face);
|
||||
|
||||
tabs = pango2_tab_array_new (1, PANGO2_TAB_POSITIONS_DEFAULT);
|
||||
pango2_tab_array_set_tab (tabs, 0, PANGO2_TAB_LEFT, width);
|
||||
gtk_label_set_tabs (self->content, tabs);
|
||||
pango2_tab_array_free (tabs);
|
||||
|
||||
for (int i = 0; i < hb_ot_var_get_named_instance_count (hb_face); i++)
|
||||
{
|
||||
unsigned int n_coords = n_axes;
|
||||
Pango2Attribute *attr;
|
||||
GString *variations;
|
||||
hb_ot_name_id_t name_id;
|
||||
char name[20];
|
||||
unsigned int name_len = 20;
|
||||
|
||||
name_id = hb_ot_var_named_instance_get_subfamily_name_id (hb_face, i);
|
||||
hb_ot_name_get_utf8 (hb_face, name_id, HB_LANGUAGE_INVALID, &name_len, name);
|
||||
|
||||
g_string_append_printf (str, "%s\t", name);
|
||||
end = str->len;
|
||||
|
||||
attr = pango2_attr_font_desc_new (label_desc);
|
||||
pango2_attribute_set_range (attr, start, end);
|
||||
pango2_attr_list_insert (attrs, attr);
|
||||
start = end;
|
||||
|
||||
hb_ot_var_named_instance_get_design_coords (hb_face, i, &n_coords, coords);
|
||||
variations = g_string_new ("");
|
||||
for (int j = 0; j < n_axes; j++)
|
||||
{
|
||||
char buf[5] = { 0, };
|
||||
|
||||
if (variations->len > 0)
|
||||
g_string_append_c (variations, ',');
|
||||
hb_tag_to_string (axes[j].tag, buf);
|
||||
g_string_append_printf (variations, "%s=%f", buf, coords[j]);
|
||||
}
|
||||
|
||||
g_string_append (str, self->sample_text);
|
||||
g_string_append (str, "
"); /* Unicode line separator */
|
||||
end = start + text_len + strlen ("
");
|
||||
|
||||
pango2_font_description_set_variations (desc, variations->str);
|
||||
g_string_free (variations, TRUE);
|
||||
|
||||
attr = pango2_attr_font_desc_new (desc);
|
||||
pango2_attribute_set_range (attr, start, end);
|
||||
pango2_attr_list_insert (attrs, attr);
|
||||
start = end;
|
||||
}
|
||||
|
||||
pango2_font_description_free (label_desc);
|
||||
|
||||
gtk_label_set_text (self->content, str->str);
|
||||
gtk_label_set_attributes (self->content, attrs);
|
||||
g_string_free (str, TRUE);
|
||||
|
||||
pango2_attr_list_unref (attrs);
|
||||
pango2_font_description_free (desc);
|
||||
|
||||
fg = gdk_rgba_to_string (&self->foreground);
|
||||
bg = gdk_rgba_to_string (&self->background);
|
||||
css = g_strdup_printf (".content { caret-color: %s; background-color: %s; }", fg, bg);
|
||||
gtk_css_provider_load_from_data (self->bg_provider, css, strlen (css));
|
||||
g_free (css);
|
||||
g_free (fg);
|
||||
g_free (bg);
|
||||
|
||||
g_object_unref (font);
|
||||
}
|
||||
|
||||
static void
|
||||
style_view_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
StyleView *self = STYLE_VIEW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FONT_MAP:
|
||||
g_set_object (&self->font_map, g_value_get_object (value));
|
||||
gtk_widget_set_font_map (GTK_WIDGET (self->content), self->font_map);
|
||||
update_has_styles (self);
|
||||
break;
|
||||
|
||||
case PROP_FONT_DESC:
|
||||
pango2_font_description_free (self->font_desc);
|
||||
self->font_desc = pango2_font_description_copy (g_value_get_boxed (value));
|
||||
update_has_styles (self);
|
||||
break;
|
||||
|
||||
case PROP_SIZE:
|
||||
self->size = g_value_get_float (value);
|
||||
break;
|
||||
|
||||
case PROP_LETTERSPACING:
|
||||
self->letterspacing = g_value_get_int (value);
|
||||
break;
|
||||
|
||||
case PROP_LINE_HEIGHT:
|
||||
self->line_height = g_value_get_float (value);
|
||||
break;
|
||||
|
||||
case PROP_FOREGROUND:
|
||||
self->foreground = *(GdkRGBA *)g_value_get_boxed (value);
|
||||
break;
|
||||
|
||||
case PROP_BACKGROUND:
|
||||
self->background = *(GdkRGBA *)g_value_get_boxed (value);
|
||||
break;
|
||||
|
||||
case PROP_VARIATIONS:
|
||||
g_free (self->variations);
|
||||
self->variations = g_strdup (g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_FEATURES:
|
||||
g_free (self->features);
|
||||
self->features = g_strdup (g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_PALETTE:
|
||||
g_free (self->palette);
|
||||
self->palette = g_strdup (g_value_get_string (value));
|
||||
self->palette_quark = g_quark_from_string (self->palette);
|
||||
break;
|
||||
|
||||
case PROP_SAMPLE_TEXT:
|
||||
g_free (self->sample_text);
|
||||
self->sample_text = g_strdup (g_value_get_string (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
|
||||
update_view (self);
|
||||
}
|
||||
|
||||
static void
|
||||
style_view_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
StyleView *self = STYLE_VIEW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FONT_MAP:
|
||||
g_value_set_object (value, self->font_map);
|
||||
break;
|
||||
|
||||
case PROP_FONT_DESC:
|
||||
g_value_set_boxed (value, self->font_desc);
|
||||
break;
|
||||
|
||||
case PROP_SIZE:
|
||||
g_value_set_float (value, self->size);
|
||||
break;
|
||||
|
||||
case PROP_LETTERSPACING:
|
||||
g_value_set_int (value, self->letterspacing);
|
||||
break;
|
||||
|
||||
case PROP_LINE_HEIGHT:
|
||||
g_value_set_float (value, self->line_height);
|
||||
break;
|
||||
|
||||
case PROP_FOREGROUND:
|
||||
g_value_set_boxed (value, &self->foreground);
|
||||
break;
|
||||
|
||||
case PROP_BACKGROUND:
|
||||
g_value_set_boxed (value, &self->background);
|
||||
break;
|
||||
|
||||
case PROP_VARIATIONS:
|
||||
g_value_set_string (value, self->variations);
|
||||
break;
|
||||
|
||||
case PROP_FEATURES:
|
||||
g_value_set_string (value, self->features);
|
||||
break;
|
||||
|
||||
case PROP_PALETTE:
|
||||
g_value_set_string (value, self->palette);
|
||||
break;
|
||||
|
||||
case PROP_SAMPLE_TEXT:
|
||||
g_value_set_string (value, self->sample_text);
|
||||
break;
|
||||
|
||||
case PROP_HAS_STYLES:
|
||||
g_value_set_boolean (value, self->has_styles);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
style_view_class_init (StyleViewClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->dispose = style_view_dispose;
|
||||
object_class->finalize = style_view_finalize;
|
||||
object_class->get_property = style_view_get_property;
|
||||
object_class->set_property = style_view_set_property;
|
||||
|
||||
properties[PROP_FONT_MAP] =
|
||||
g_param_spec_object ("font-map", "", "",
|
||||
PANGO2_TYPE_FONT_MAP,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_FONT_DESC] =
|
||||
g_param_spec_boxed ("font-desc", "", "",
|
||||
PANGO2_TYPE_FONT_DESCRIPTION,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_SIZE] =
|
||||
g_param_spec_float ("size", "", "",
|
||||
0., 100., 12.,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_LETTERSPACING] =
|
||||
g_param_spec_int ("letterspacing", "", "",
|
||||
-G_MAXINT, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_LINE_HEIGHT] =
|
||||
g_param_spec_float ("line-height", "", "",
|
||||
0., 100., 1.,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_FOREGROUND] =
|
||||
g_param_spec_boxed ("foreground", "", "",
|
||||
GDK_TYPE_RGBA,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_BACKGROUND] =
|
||||
g_param_spec_boxed ("background", "", "",
|
||||
GDK_TYPE_RGBA,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_VARIATIONS] =
|
||||
g_param_spec_string ("variations", "", "",
|
||||
"",
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_FEATURES] =
|
||||
g_param_spec_string ("features", "", "",
|
||||
"",
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_PALETTE] =
|
||||
g_param_spec_string ("palette", "", "",
|
||||
PANGO2_COLOR_PALETTE_DEFAULT,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_SAMPLE_TEXT] =
|
||||
g_param_spec_string ("sample-text", "", "",
|
||||
"",
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_HAS_STYLES] =
|
||||
g_param_spec_boolean ("has-styles", "", "",
|
||||
FALSE,
|
||||
G_PARAM_READABLE);
|
||||
|
||||
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/fontexplorer/styleview.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), StyleView, swin);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), StyleView, content);
|
||||
|
||||
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "styleview");
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define STYLE_VIEW_TYPE (style_view_get_type ())
|
||||
#define STYLE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STYLE_VIEW_TYPE, StyleView))
|
||||
|
||||
|
||||
typedef struct _StyleView StyleView;
|
||||
typedef struct _StyleViewClass StyleViewClass;
|
||||
|
||||
|
||||
GType style_view_get_type (void);
|
||||
@@ -1,31 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="StyleView" parent="GtkWidget">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<style>
|
||||
<class name="view"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="swin">
|
||||
<property name="hscrollbar-policy">automatic</property>
|
||||
<property name="vscrollbar-policy">automatic</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="content">
|
||||
<property name="label">Content</property>
|
||||
<property name="wrap">0</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<property name="halign">fill</property>
|
||||
<property name="valign">fill</property>
|
||||
<style>
|
||||
<class name="content"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -1,401 +0,0 @@
|
||||
#include "waterfallview.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <hb-ot.h>
|
||||
|
||||
#include "glyphitem.h"
|
||||
#include "glyphmodel.h"
|
||||
#include "glyphview.h"
|
||||
|
||||
enum {
|
||||
PROP_FONT_MAP = 1,
|
||||
PROP_FONT_DESC,
|
||||
PROP_SIZE,
|
||||
PROP_LETTERSPACING,
|
||||
PROP_LINE_HEIGHT,
|
||||
PROP_FOREGROUND,
|
||||
PROP_BACKGROUND,
|
||||
PROP_VARIATIONS,
|
||||
PROP_FEATURES,
|
||||
PROP_PALETTE,
|
||||
PROP_SAMPLE_TEXT,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
struct _WaterfallView
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
GtkLabel *content;
|
||||
GtkScrolledWindow *swin;
|
||||
|
||||
Pango2FontMap *font_map;
|
||||
Pango2FontDescription *font_desc;
|
||||
float size;
|
||||
char *variations;
|
||||
char *features;
|
||||
char *palette;
|
||||
GQuark palette_quark;
|
||||
int letterspacing;
|
||||
float line_height;
|
||||
GdkRGBA foreground;
|
||||
GdkRGBA background;
|
||||
GtkCssProvider *bg_provider;
|
||||
char *sample_text;
|
||||
};
|
||||
|
||||
struct _WaterfallViewClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(WaterfallView, waterfall_view, GTK_TYPE_WIDGET);
|
||||
|
||||
static void
|
||||
waterfall_view_init (WaterfallView *self)
|
||||
{
|
||||
self->font_map = g_object_ref (pango2_font_map_get_default ());
|
||||
self->font_desc = pango2_font_description_from_string ("sans 12");
|
||||
self->size = 12.;
|
||||
self->letterspacing = 0;
|
||||
self->line_height = 1.;
|
||||
self->variations = g_strdup ("");
|
||||
self->features = g_strdup ("");
|
||||
self->palette = g_strdup (PANGO2_COLOR_PALETTE_DEFAULT);
|
||||
self->palette_quark = g_quark_from_string (self->palette);
|
||||
self->foreground = (GdkRGBA){0., 0., 0., 1. };
|
||||
self->background = (GdkRGBA){1., 1., 1., 1. };
|
||||
self->sample_text = g_strdup ("Some sample text is better than other sample text");
|
||||
|
||||
gtk_widget_set_layout_manager (GTK_WIDGET (self),
|
||||
gtk_box_layout_new (GTK_ORIENTATION_VERTICAL));
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
self->bg_provider = gtk_css_provider_new ();
|
||||
gtk_style_context_add_provider (gtk_widget_get_style_context (GTK_WIDGET (self->content)),
|
||||
GTK_STYLE_PROVIDER (self->bg_provider), 800);
|
||||
}
|
||||
|
||||
static void
|
||||
waterfall_view_dispose (GObject *object)
|
||||
{
|
||||
gtk_widget_clear_template (GTK_WIDGET (object), WATERFALL_VIEW_TYPE);
|
||||
|
||||
G_OBJECT_CLASS (waterfall_view_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
waterfall_view_finalize (GObject *object)
|
||||
{
|
||||
WaterfallView *self = WATERFALL_VIEW (object);
|
||||
|
||||
g_clear_object (&self->font_map);
|
||||
pango2_font_description_free (self->font_desc);
|
||||
g_free (self->variations);
|
||||
g_free (self->features);
|
||||
g_free (self->palette);
|
||||
|
||||
G_OBJECT_CLASS (waterfall_view_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
update_view (WaterfallView *self)
|
||||
{
|
||||
Pango2FontDescription *desc;
|
||||
Pango2AttrList *attrs;
|
||||
char *fg, *bg, *css;
|
||||
GString *str;
|
||||
int sizes[] = { 7, 8, 9, 10, 12, 14, 16, 20, 24, 30, 40, 50, 60, 70, 90, 120 };
|
||||
int start, end, text_len;
|
||||
Pango2TabArray *tabs;
|
||||
|
||||
desc = pango2_font_description_copy_static (self->font_desc);
|
||||
pango2_font_description_set_size (desc, 12 * PANGO2_SCALE);
|
||||
pango2_font_description_set_variations (desc, self->variations);
|
||||
|
||||
attrs = pango2_attr_list_new ();
|
||||
pango2_attr_list_insert (attrs, pango2_attr_font_desc_new (desc));
|
||||
pango2_attr_list_insert (attrs, pango2_attr_size_new (self->size * PANGO2_SCALE));
|
||||
pango2_attr_list_insert (attrs, pango2_attr_line_height_new (self->line_height));
|
||||
pango2_attr_list_insert (attrs, pango2_attr_letter_spacing_new (self->letterspacing));
|
||||
pango2_attr_list_insert (attrs, pango2_attr_foreground_new (&(Pango2Color){65535 * self->foreground.red,
|
||||
65535 * self->foreground.green,
|
||||
65535 * self->foreground.blue,
|
||||
65535 * self->foreground.alpha}));
|
||||
pango2_attr_list_insert (attrs, pango2_attr_font_features_new (self->features));
|
||||
pango2_attr_list_insert (attrs, pango2_attr_palette_new (self->palette));
|
||||
|
||||
pango2_font_description_free (desc);
|
||||
|
||||
tabs = pango2_tab_array_new (2, PANGO2_TAB_POSITIONS_SPACES);
|
||||
pango2_tab_array_set_tab (tabs, 0, PANGO2_TAB_RIGHT, 5);
|
||||
pango2_tab_array_set_tab (tabs, 1, PANGO2_TAB_LEFT, 8);
|
||||
|
||||
gtk_label_set_tabs (self->content, tabs);
|
||||
pango2_tab_array_free (tabs);
|
||||
|
||||
str = g_string_new ("");
|
||||
start = 0;
|
||||
text_len = strlen (self->sample_text);
|
||||
for (int i = 0; i < G_N_ELEMENTS (sizes); i++)
|
||||
{
|
||||
Pango2Attribute *attr;
|
||||
|
||||
g_string_append_printf (str, "\t%d\t", sizes[i]);
|
||||
|
||||
end = str->len;
|
||||
|
||||
attr = pango2_attr_family_new ("Cantarell");
|
||||
pango2_attribute_set_range (attr, start, end);
|
||||
pango2_attr_list_insert (attrs, attr);
|
||||
|
||||
attr = pango2_attr_weight_new (PANGO2_WEIGHT_NORMAL);
|
||||
pango2_attribute_set_range (attr, start, end);
|
||||
pango2_attr_list_insert (attrs, attr);
|
||||
|
||||
attr = pango2_attr_style_new (PANGO2_STYLE_NORMAL);
|
||||
pango2_attribute_set_range (attr, start, end);
|
||||
pango2_attr_list_insert (attrs, attr);
|
||||
|
||||
attr = pango2_attr_size_new (12 * PANGO2_SCALE);
|
||||
pango2_attribute_set_range (attr, start, end);
|
||||
pango2_attr_list_insert (attrs, attr);
|
||||
|
||||
attr = pango2_attr_font_features_new ("tnum=1");
|
||||
pango2_attribute_set_range (attr, start, end);
|
||||
pango2_attr_list_insert (attrs, attr);
|
||||
|
||||
attr = pango2_attr_letter_spacing_new (0);
|
||||
pango2_attribute_set_range (attr, start, end);
|
||||
pango2_attr_list_insert (attrs, attr);
|
||||
start = end;
|
||||
|
||||
g_string_append (str, self->sample_text);
|
||||
g_string_append (str, "
"); /* Unicode line separator */
|
||||
end = start + text_len + strlen ("
");
|
||||
|
||||
attr = pango2_attr_size_new (sizes[i] * PANGO2_SCALE);
|
||||
pango2_attribute_set_range (attr, start, end);
|
||||
pango2_attr_list_insert (attrs, attr);
|
||||
|
||||
start = end;
|
||||
}
|
||||
gtk_label_set_text (self->content, str->str);
|
||||
gtk_label_set_attributes (self->content, attrs);
|
||||
g_string_free (str, TRUE);
|
||||
|
||||
pango2_attr_list_unref (attrs);
|
||||
|
||||
fg = gdk_rgba_to_string (&self->foreground);
|
||||
bg = gdk_rgba_to_string (&self->background);
|
||||
css = g_strdup_printf (".content { caret-color: %s; background-color: %s; }", fg, bg);
|
||||
gtk_css_provider_load_from_data (self->bg_provider, css, strlen (css));
|
||||
g_free (css);
|
||||
g_free (fg);
|
||||
g_free (bg);
|
||||
}
|
||||
|
||||
static void
|
||||
waterfall_view_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
WaterfallView *self = WATERFALL_VIEW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FONT_MAP:
|
||||
g_set_object (&self->font_map, g_value_get_object (value));
|
||||
gtk_widget_set_font_map (GTK_WIDGET (self->content), self->font_map);
|
||||
break;
|
||||
|
||||
case PROP_FONT_DESC:
|
||||
pango2_font_description_free (self->font_desc);
|
||||
self->font_desc = pango2_font_description_copy (g_value_get_boxed (value));
|
||||
break;
|
||||
|
||||
case PROP_SIZE:
|
||||
self->size = g_value_get_float (value);
|
||||
break;
|
||||
|
||||
case PROP_LETTERSPACING:
|
||||
self->letterspacing = g_value_get_int (value);
|
||||
break;
|
||||
|
||||
case PROP_LINE_HEIGHT:
|
||||
self->line_height = g_value_get_float (value);
|
||||
break;
|
||||
|
||||
case PROP_FOREGROUND:
|
||||
self->foreground = *(GdkRGBA *)g_value_get_boxed (value);
|
||||
break;
|
||||
|
||||
case PROP_BACKGROUND:
|
||||
self->background = *(GdkRGBA *)g_value_get_boxed (value);
|
||||
break;
|
||||
|
||||
case PROP_VARIATIONS:
|
||||
g_free (self->variations);
|
||||
self->variations = g_strdup (g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_FEATURES:
|
||||
g_free (self->features);
|
||||
self->features = g_strdup (g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_PALETTE:
|
||||
g_free (self->palette);
|
||||
self->palette = g_strdup (g_value_get_string (value));
|
||||
self->palette_quark = g_quark_from_string (self->palette);
|
||||
break;
|
||||
|
||||
case PROP_SAMPLE_TEXT:
|
||||
g_free (self->sample_text);
|
||||
self->sample_text = g_strdup (g_value_get_string (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
|
||||
update_view (self);
|
||||
}
|
||||
|
||||
static void
|
||||
waterfall_view_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
WaterfallView *self = WATERFALL_VIEW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FONT_MAP:
|
||||
g_value_set_object (value, self->font_map);
|
||||
break;
|
||||
|
||||
case PROP_FONT_DESC:
|
||||
g_value_set_boxed (value, self->font_desc);
|
||||
break;
|
||||
|
||||
case PROP_SIZE:
|
||||
g_value_set_float (value, self->size);
|
||||
break;
|
||||
|
||||
case PROP_LETTERSPACING:
|
||||
g_value_set_int (value, self->letterspacing);
|
||||
break;
|
||||
|
||||
case PROP_LINE_HEIGHT:
|
||||
g_value_set_float (value, self->line_height);
|
||||
break;
|
||||
|
||||
case PROP_FOREGROUND:
|
||||
g_value_set_boxed (value, &self->foreground);
|
||||
break;
|
||||
|
||||
case PROP_BACKGROUND:
|
||||
g_value_set_boxed (value, &self->background);
|
||||
break;
|
||||
|
||||
case PROP_VARIATIONS:
|
||||
g_value_set_string (value, self->variations);
|
||||
break;
|
||||
|
||||
case PROP_FEATURES:
|
||||
g_value_set_string (value, self->features);
|
||||
break;
|
||||
|
||||
case PROP_PALETTE:
|
||||
g_value_set_string (value, self->palette);
|
||||
break;
|
||||
|
||||
case PROP_SAMPLE_TEXT:
|
||||
g_value_set_string (value, self->sample_text);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
waterfall_view_class_init (WaterfallViewClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->dispose = waterfall_view_dispose;
|
||||
object_class->finalize = waterfall_view_finalize;
|
||||
object_class->get_property = waterfall_view_get_property;
|
||||
object_class->set_property = waterfall_view_set_property;
|
||||
|
||||
properties[PROP_FONT_MAP] =
|
||||
g_param_spec_object ("font-map", "", "",
|
||||
PANGO2_TYPE_FONT_MAP,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_FONT_DESC] =
|
||||
g_param_spec_boxed ("font-desc", "", "",
|
||||
PANGO2_TYPE_FONT_DESCRIPTION,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_SIZE] =
|
||||
g_param_spec_float ("size", "", "",
|
||||
0., 100., 12.,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_LETTERSPACING] =
|
||||
g_param_spec_int ("letterspacing", "", "",
|
||||
-G_MAXINT, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_LINE_HEIGHT] =
|
||||
g_param_spec_float ("line-height", "", "",
|
||||
0., 100., 1.,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_FOREGROUND] =
|
||||
g_param_spec_boxed ("foreground", "", "",
|
||||
GDK_TYPE_RGBA,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_BACKGROUND] =
|
||||
g_param_spec_boxed ("background", "", "",
|
||||
GDK_TYPE_RGBA,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_VARIATIONS] =
|
||||
g_param_spec_string ("variations", "", "",
|
||||
"",
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_FEATURES] =
|
||||
g_param_spec_string ("features", "", "",
|
||||
"",
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_PALETTE] =
|
||||
g_param_spec_string ("palette", "", "",
|
||||
PANGO2_COLOR_PALETTE_DEFAULT,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_SAMPLE_TEXT] =
|
||||
g_param_spec_string ("sample-text", "", "",
|
||||
"",
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/fontexplorer/waterfallview.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), WaterfallView, swin);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), WaterfallView, content);
|
||||
|
||||
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "waterfallview");
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define WATERFALL_VIEW_TYPE (waterfall_view_get_type ())
|
||||
#define WATERFALL_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), WATERFALL_VIEW_TYPE, WaterfallView))
|
||||
|
||||
|
||||
typedef struct _WaterfallView WaterfallView;
|
||||
typedef struct _WaterfallViewClass WaterfallViewClass;
|
||||
|
||||
|
||||
GType waterfall_view_get_type (void);
|
||||
@@ -1,31 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="WaterfallView" parent="GtkWidget">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<style>
|
||||
<class name="view"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="swin">
|
||||
<property name="hscrollbar-policy">automatic</property>
|
||||
<property name="vscrollbar-policy">automatic</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="content">
|
||||
<property name="label">Content</property>
|
||||
<property name="wrap">0</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<property name="halign">fill</property>
|
||||
<property name="valign">fill</property>
|
||||
<style>
|
||||
<class name="content"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -504,6 +504,8 @@ demo_application_window_dispose (GObject *object)
|
||||
|
||||
demo_application_window_store_state (window);
|
||||
|
||||
gtk_widget_dispose_template (GTK_WIDGET (window), demo_application_window_get_type ());
|
||||
|
||||
G_OBJECT_CLASS (demo_application_window_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
enum
|
||||
{
|
||||
ICON_NAME_COL,
|
||||
@@ -260,13 +262,12 @@ mask_entry_set_background (MaskEntry *entry)
|
||||
{
|
||||
if (!g_regex_match_simple (entry->mask, gtk_editable_get_text (GTK_EDITABLE (entry)), 0, 0))
|
||||
{
|
||||
Pango2AttrList *attrs;
|
||||
Pango2Color color = { 65535, 32767, 32767, 65535 };
|
||||
PangoAttrList *attrs;
|
||||
|
||||
attrs = pango2_attr_list_new ();
|
||||
pango2_attr_list_insert (attrs, pango2_attr_foreground_new (&color));
|
||||
attrs = pango_attr_list_new ();
|
||||
pango_attr_list_insert (attrs, pango_attr_foreground_new (65535, 32767, 32767));
|
||||
gtk_entry_set_attributes (GTK_ENTRY (entry), attrs);
|
||||
pango2_attr_list_unref (attrs);
|
||||
pango_attr_list_unref (attrs);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
/* Theming/CSS Accordion
|
||||
*
|
||||
* A simple accordion demo written using CSS transitions and multiple backgrounds
|
||||
*
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static void
|
||||
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
||||
destroy_provider (GtkWidget *window,
|
||||
GtkStyleProvider *provider)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
apply_css (child, provider);
|
||||
gtk_style_context_remove_provider_for_display (gtk_widget_get_display (window), provider);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
@@ -24,8 +20,8 @@ do_css_accordion (GtkWidget *do_widget)
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *container, *child;
|
||||
GtkStyleProvider *provider;
|
||||
GtkWidget *container, *styled_box, *child;
|
||||
GtkCssProvider *provider;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_title (GTK_WINDOW (window), "CSS Accordion");
|
||||
@@ -33,10 +29,13 @@ do_css_accordion (GtkWidget *do_widget)
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 300);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
styled_box = gtk_frame_new (NULL);
|
||||
gtk_window_set_child (GTK_WINDOW (window), styled_box);
|
||||
gtk_widget_add_css_class (styled_box, "accordion");
|
||||
container = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_widget_set_halign (container, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (container, GTK_ALIGN_CENTER);
|
||||
gtk_window_set_child (GTK_WINDOW (window), container);
|
||||
gtk_frame_set_child (GTK_FRAME (styled_box), container);
|
||||
|
||||
child = gtk_button_new_with_label ("This");
|
||||
gtk_box_append (GTK_BOX (container), child);
|
||||
@@ -56,10 +55,16 @@ do_css_accordion (GtkWidget *do_widget)
|
||||
child = gtk_button_new_with_label (":-)");
|
||||
gtk_box_append (GTK_BOX (container), child);
|
||||
|
||||
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||
gtk_css_provider_load_from_resource (GTK_CSS_PROVIDER (provider), "/css_accordion/css_accordion.css");
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (provider, "/css_accordion/css_accordion.css");
|
||||
|
||||
apply_css (window, provider);
|
||||
gtk_style_context_add_provider_for_display (gtk_widget_get_display (window),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (destroy_provider), provider);
|
||||
g_object_unref (provider);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
@import url("resource://css_accordion/reset.css");
|
||||
.accordion, .accordion * {
|
||||
all: unset;
|
||||
|
||||
* {
|
||||
transition-property: color, background-color, border-color, background-image, padding, border-width;
|
||||
transition-duration: 1s;
|
||||
|
||||
font: 20px Cantarell;
|
||||
}
|
||||
|
||||
window {
|
||||
.accordion {
|
||||
background: linear-gradient(153deg, #151515, #151515 5px, transparent 5px) 0 0,
|
||||
linear-gradient(333deg, #151515, #151515 5px, transparent 5px) 10px 5px,
|
||||
linear-gradient(153deg, #222, #222 5px, transparent 5px) 0 5px,
|
||||
@@ -18,7 +18,7 @@ window {
|
||||
background-size: 20px 20px;
|
||||
}
|
||||
|
||||
button {
|
||||
.accordion button {
|
||||
color: black;
|
||||
background-color: #bbb;
|
||||
border-style: solid;
|
||||
@@ -28,25 +28,25 @@ button {
|
||||
padding: 12px 4px;
|
||||
}
|
||||
|
||||
button:first-child {
|
||||
.accordion button:first-child {
|
||||
border-radius: 5px 0 0 5px;
|
||||
}
|
||||
|
||||
button:last-child {
|
||||
.accordion button:last-child {
|
||||
border-radius: 0 5px 5px 0;
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
.accordion button:hover {
|
||||
padding: 12px 48px;
|
||||
background-color: #4870bc;
|
||||
}
|
||||
|
||||
button *:hover {
|
||||
.accordion button *:hover {
|
||||
color: white;
|
||||
}
|
||||
|
||||
button:hover:active,
|
||||
button:active {
|
||||
.accordion button:hover:active,
|
||||
.accordion button:active {
|
||||
background-color: #993401;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static void
|
||||
show_parsing_error (GtkCssProvider *provider,
|
||||
GtkCssSection *section,
|
||||
@@ -84,11 +86,11 @@ do_css_basics (GtkWidget *do_widget)
|
||||
text = gtk_text_buffer_new (NULL);
|
||||
gtk_text_buffer_create_tag (text,
|
||||
"warning",
|
||||
"underline", PANGO2_LINE_STYLE_SOLID,
|
||||
"underline", PANGO_UNDERLINE_SINGLE,
|
||||
NULL);
|
||||
gtk_text_buffer_create_tag (text,
|
||||
"error",
|
||||
"underline", PANGO2_LINE_STYLE_DOTTED,
|
||||
"underline", PANGO_UNDERLINE_ERROR,
|
||||
NULL);
|
||||
|
||||
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static void
|
||||
show_parsing_error (GtkCssProvider *provider,
|
||||
GtkCssSection *section,
|
||||
@@ -122,11 +124,11 @@ do_css_multiplebgs (GtkWidget *do_widget)
|
||||
text = gtk_text_buffer_new (NULL);
|
||||
gtk_text_buffer_create_tag (text,
|
||||
"warning",
|
||||
"underline", PANGO2_LINE_STYLE_SOLID,
|
||||
"underline", PANGO_UNDERLINE_SINGLE,
|
||||
NULL);
|
||||
gtk_text_buffer_create_tag (text,
|
||||
"error",
|
||||
"underline", PANGO2_LINE_STYLE_DOTTED,
|
||||
"underline", PANGO_UNDERLINE_ERROR,
|
||||
NULL);
|
||||
|
||||
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static void
|
||||
show_parsing_error (GtkCssProvider *provider,
|
||||
GtkCssSection *section,
|
||||
@@ -93,11 +95,11 @@ do_css_pixbufs (GtkWidget *do_widget)
|
||||
text = gtk_text_buffer_new (NULL);
|
||||
gtk_text_buffer_create_tag (text,
|
||||
"warning",
|
||||
"underline", PANGO2_LINE_STYLE_SOLID,
|
||||
"underline", PANGO_UNDERLINE_SINGLE,
|
||||
NULL);
|
||||
gtk_text_buffer_create_tag (text,
|
||||
"error",
|
||||
"underline", PANGO2_LINE_STYLE_DOTTED,
|
||||
"underline", PANGO_UNDERLINE_ERROR,
|
||||
NULL);
|
||||
|
||||
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static void
|
||||
show_parsing_error (GtkCssProvider *provider,
|
||||
GtkCssSection *section,
|
||||
@@ -111,11 +113,11 @@ do_css_shadows (GtkWidget *do_widget)
|
||||
text = gtk_text_buffer_new (NULL);
|
||||
gtk_text_buffer_create_tag (text,
|
||||
"warning",
|
||||
"underline", PANGO2_LINE_STYLE_SOLID,
|
||||
"underline", PANGO_UNDERLINE_SINGLE,
|
||||
NULL);
|
||||
gtk_text_buffer_create_tag (text,
|
||||
"error",
|
||||
"underline", PANGO2_LINE_STYLE_DOTTED,
|
||||
"underline", PANGO_UNDERLINE_ERROR,
|
||||
NULL);
|
||||
|
||||
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
</gresource>
|
||||
<gresource prefix="/css_accordion">
|
||||
<file>css_accordion.css</file>
|
||||
<file>reset.css</file>
|
||||
</gresource>
|
||||
<gresource prefix="/css_basics">
|
||||
<file>css_basics.css</file>
|
||||
@@ -428,6 +427,8 @@
|
||||
<file>icons/16x16/emotes/face-laugh-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/status/battery-caution-charging-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/categories/applications-other.png</file>
|
||||
<file>icons/48x48/status/starred.png</file>
|
||||
<file alias="icons/scalable/apps/org.gtk.Demo4.svg">data/scalable/apps/org.gtk.Demo4.svg</file>
|
||||
</gresource>
|
||||
<gresource prefix="/org/gtk/Demo4/gtk">
|
||||
<file preprocess="xml-stripblanks">help-overlay.ui</file>
|
||||
|
||||
@@ -37,7 +37,8 @@ demo3_widget_dispose (GObject *object)
|
||||
Demo3Widget *self = DEMO3_WIDGET (object);
|
||||
|
||||
g_clear_object (&self->paintable);
|
||||
g_clear_pointer (&self->menu, gtk_widget_unparent);
|
||||
|
||||
gtk_widget_dispose_template (GTK_WIDGET (self), DEMO3_TYPE_WIDGET);
|
||||
|
||||
G_OBJECT_CLASS (demo3_widget_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
G_DECLARE_FINAL_TYPE (CanvasItem, canvas_item, CANVAS, ITEM, GtkWidget)
|
||||
|
||||
struct _CanvasItem {
|
||||
@@ -24,6 +25,9 @@ struct _CanvasItem {
|
||||
double delta;
|
||||
|
||||
GtkWidget *editor;
|
||||
|
||||
GtkStyleProvider *provider;
|
||||
char *css_class;
|
||||
};
|
||||
|
||||
struct _CanvasItemClass {
|
||||
@@ -34,32 +38,41 @@ G_DEFINE_TYPE (CanvasItem, canvas_item, GTK_TYPE_WIDGET)
|
||||
|
||||
static int n_items = 0;
|
||||
|
||||
static void
|
||||
unstyle_item (CanvasItem *item)
|
||||
{
|
||||
if (item->provider)
|
||||
{
|
||||
gtk_style_context_remove_provider_for_display (gtk_widget_get_display (item->label), item->provider);
|
||||
g_clear_object (&item->provider);
|
||||
}
|
||||
|
||||
if (item->css_class)
|
||||
{
|
||||
gtk_widget_remove_css_class (item->label, item->css_class);
|
||||
g_clear_pointer (&item->css_class, g_free);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_color (CanvasItem *item,
|
||||
GdkRGBA *color)
|
||||
{
|
||||
char *css;
|
||||
char *str;
|
||||
GtkStyleContext *context;
|
||||
GtkCssProvider *provider;
|
||||
const char *old_class;
|
||||
const char *name;
|
||||
|
||||
unstyle_item (item);
|
||||
|
||||
str = gdk_rgba_to_string (color);
|
||||
css = g_strdup_printf ("* { background: %s; }", str);
|
||||
|
||||
context = gtk_widget_get_style_context (item->label);
|
||||
provider = g_object_get_data (G_OBJECT (context), "style-provider");
|
||||
if (provider)
|
||||
gtk_style_context_remove_provider (context, GTK_STYLE_PROVIDER (provider));
|
||||
|
||||
old_class = (const char *)g_object_get_data (G_OBJECT (item->label), "css-class");
|
||||
if (old_class)
|
||||
gtk_widget_remove_css_class (item->label, old_class);
|
||||
name = gtk_widget_get_name (item->label);
|
||||
css = g_strdup_printf ("#%s { background: %s; }", name, str);
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_data (provider, css, -1);
|
||||
gtk_style_context_add_provider (gtk_widget_get_style_context (item->label), GTK_STYLE_PROVIDER (provider), 800);
|
||||
g_object_set_data_full (G_OBJECT (context), "style-provider", provider, g_object_unref);
|
||||
gtk_style_context_add_provider_for_display (gtk_widget_get_display (item->label), GTK_STYLE_PROVIDER (provider), 700);
|
||||
item->provider = GTK_STYLE_PROVIDER (provider);
|
||||
|
||||
g_free (str);
|
||||
g_free (css);
|
||||
@@ -69,21 +82,10 @@ static void
|
||||
set_css (CanvasItem *item,
|
||||
const char *class)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
GtkCssProvider *provider;
|
||||
const char *old_class;
|
||||
unstyle_item (item);
|
||||
|
||||
context = gtk_widget_get_style_context (item->label);
|
||||
provider = g_object_get_data (G_OBJECT (context), "style-provider");
|
||||
if (provider)
|
||||
gtk_style_context_remove_provider (context, GTK_STYLE_PROVIDER (provider));
|
||||
|
||||
old_class = (const char *)g_object_get_data (G_OBJECT (item->label), "css-class");
|
||||
if (old_class)
|
||||
gtk_widget_remove_css_class (item->label, old_class);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (item->label), "css-class", g_strdup (class), g_free);
|
||||
gtk_widget_add_css_class (item->label, class);
|
||||
item->css_class = g_strdup (class);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -722,6 +724,7 @@ do_dnd (GtkWidget *do_widget)
|
||||
int i;
|
||||
int x, y;
|
||||
GtkCssProvider *provider;
|
||||
GString *css;
|
||||
|
||||
button = gtk_color_button_new ();
|
||||
g_object_unref (g_object_ref_sink (button));
|
||||
@@ -733,6 +736,18 @@ do_dnd (GtkWidget *do_widget)
|
||||
800);
|
||||
g_object_unref (provider);
|
||||
|
||||
css = g_string_new ("");
|
||||
for (i = 0; colors[i]; i++)
|
||||
g_string_append_printf (css, ".canvasitem.%s { background: %s; }\n", colors[i], colors[i]);
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_data (provider, css->str, css->len);
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
800);
|
||||
g_object_unref (provider);
|
||||
g_string_free (css, TRUE);
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
|
||||
@@ -263,7 +263,7 @@ drop_down_new_from_strings (const char *const *titles,
|
||||
static char *
|
||||
get_family_name (gpointer item)
|
||||
{
|
||||
return g_strdup (pango2_font_family_get_name (PANGO2_FONT_FAMILY (item)));
|
||||
return g_strdup (pango_font_family_get_name (PANGO_FONT_FAMILY (item)));
|
||||
}
|
||||
|
||||
static char *
|
||||
@@ -326,8 +326,8 @@ bind_highlight_item (GtkSignalListItemFactory *factory,
|
||||
{
|
||||
MatchObject *obj;
|
||||
GtkWidget *label;
|
||||
Pango2AttrList *attrs;
|
||||
Pango2Attribute *attr;
|
||||
PangoAttrList *attrs;
|
||||
PangoAttribute *attr;
|
||||
const char *str;
|
||||
|
||||
obj = MATCH_OBJECT (gtk_list_item_get_item (item));
|
||||
@@ -336,14 +336,13 @@ bind_highlight_item (GtkSignalListItemFactory *factory,
|
||||
str = match_object_get_string (obj);
|
||||
|
||||
gtk_label_set_label (GTK_LABEL (label), str);
|
||||
attrs = pango2_attr_list_new ();
|
||||
attr = pango2_attr_weight_new (PANGO2_WEIGHT_BOLD);
|
||||
pango2_attribute_set_range (attr,
|
||||
match_object_get_match_start (obj),
|
||||
match_object_get_match_end (obj));
|
||||
pango2_attr_list_insert (attrs, attr);
|
||||
attrs = pango_attr_list_new ();
|
||||
attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
|
||||
attr->start_index = match_object_get_match_start (obj);
|
||||
attr->end_index = match_object_get_match_end (obj);
|
||||
pango_attr_list_insert (attrs, attr);
|
||||
gtk_label_set_attributes (GTK_LABEL (label), attrs);
|
||||
pango2_attr_list_unref (attrs);
|
||||
pango_attr_list_unref (attrs);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -435,7 +434,7 @@ do_dropdown (GtkWidget *do_widget)
|
||||
|
||||
button = gtk_drop_down_new (NULL, NULL);
|
||||
|
||||
model = G_LIST_MODEL (pango2_font_map_get_default ());
|
||||
model = G_LIST_MODEL (pango_cairo_font_map_get_default ());
|
||||
gtk_drop_down_set_model (GTK_DROP_DOWN (button), model);
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (button), 0);
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int number;
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
/* Creates a tree model containing the completions */
|
||||
static GtkTreeModel *
|
||||
create_completion_model (void)
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
enum {
|
||||
WIDTH_COLUMN,
|
||||
HEIGHT_COLUMN,
|
||||
|
||||
@@ -21,6 +21,75 @@
|
||||
#include "script-names.h"
|
||||
#include "language-names.h"
|
||||
|
||||
/* {{{ ScriptLang object */
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ScriptLang, script_lang, SCRIPT, LANG, GObject)
|
||||
|
||||
struct _ScriptLang
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
char *langname;
|
||||
unsigned int script_index;
|
||||
unsigned int lang_index;
|
||||
hb_tag_t lang_tag;
|
||||
};
|
||||
|
||||
struct _ScriptLangClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ScriptLang, script_lang, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
script_lang_init (ScriptLang *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
script_lang_finalize (GObject *object)
|
||||
{
|
||||
ScriptLang *self = SCRIPT_LANG (object);
|
||||
|
||||
g_free (self->langname);
|
||||
|
||||
G_OBJECT_CLASS (script_lang_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
script_lang_class_init (ScriptLangClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->finalize = script_lang_finalize;
|
||||
}
|
||||
|
||||
static ScriptLang *
|
||||
script_lang_new (const char *langname,
|
||||
unsigned int script_index,
|
||||
unsigned int lang_index,
|
||||
hb_tag_t lang_tag)
|
||||
{
|
||||
ScriptLang *self;
|
||||
|
||||
self = g_object_new (script_lang_get_type (), NULL);
|
||||
|
||||
self->langname = g_strdup (langname);
|
||||
self->script_index = script_index;
|
||||
self->lang_index = lang_index;
|
||||
self->lang_tag = lang_tag;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static char *
|
||||
script_lang_get_langname (ScriptLang *self)
|
||||
{
|
||||
return g_strdup (self->langname);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
#define MAKE_TAG(a,b,c,d) (unsigned int)(((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
|
||||
|
||||
@@ -35,10 +104,9 @@ typedef struct {
|
||||
typedef struct {
|
||||
unsigned int start;
|
||||
unsigned int end;
|
||||
Pango2FontDescription *desc;
|
||||
PangoFontDescription *desc;
|
||||
char *features;
|
||||
char *palette;
|
||||
Pango2Language *language;
|
||||
PangoLanguage *language;
|
||||
} Range;
|
||||
|
||||
typedef struct {
|
||||
@@ -59,8 +127,6 @@ typedef struct {
|
||||
GtkWidget *script_lang;
|
||||
GtkWidget *feature_list;
|
||||
GtkWidget *variations_grid;
|
||||
GtkWidget *colors_grid;
|
||||
GtkWidget *first_palette;
|
||||
GtkWidget *instance_combo;
|
||||
GtkWidget *stack;
|
||||
GtkWidget *entry;
|
||||
@@ -84,7 +150,6 @@ typedef struct {
|
||||
GtkWidget *swin;
|
||||
GtkCssProvider *provider;
|
||||
int sample;
|
||||
int palette;
|
||||
} FontFeaturesDemo;
|
||||
|
||||
static void
|
||||
@@ -98,6 +163,10 @@ demo_free (gpointer data)
|
||||
g_clear_pointer (&demo->axes, g_hash_table_unref);
|
||||
g_clear_pointer (&demo->text, g_free);
|
||||
|
||||
gtk_style_context_remove_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (demo->provider));
|
||||
g_object_unref (demo->provider);
|
||||
|
||||
g_free (demo);
|
||||
}
|
||||
|
||||
@@ -206,12 +275,12 @@ font_features_reset_basic (void)
|
||||
static void
|
||||
update_basic (void)
|
||||
{
|
||||
Pango2FontDescription *desc;
|
||||
PangoFontDescription *desc;
|
||||
|
||||
desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (demo->font));
|
||||
|
||||
gtk_adjustment_set_value (demo->size_adjustment,
|
||||
pango2_font_description_get_size (desc) / (double) PANGO2_SCALE);
|
||||
pango_font_description_get_size (desc) / (double) PANGO_SCALE);
|
||||
}
|
||||
|
||||
static void add_font_variations (GString *s);
|
||||
@@ -222,9 +291,8 @@ free_range (gpointer data)
|
||||
Range *range = data;
|
||||
|
||||
if (range->desc)
|
||||
pango2_font_description_free (range->desc);
|
||||
pango_font_description_free (range->desc);
|
||||
g_free (range->features);
|
||||
g_free (range->palette);
|
||||
g_free (range);
|
||||
}
|
||||
|
||||
@@ -249,10 +317,9 @@ compare_range (gconstpointer a, gconstpointer b)
|
||||
static void
|
||||
ensure_range (unsigned int start,
|
||||
unsigned int end,
|
||||
Pango2FontDescription *desc,
|
||||
PangoFontDescription *desc,
|
||||
const char *features,
|
||||
const char *palette,
|
||||
Pango2Language *language)
|
||||
PangoLanguage *language)
|
||||
{
|
||||
GList *l;
|
||||
Range *range;
|
||||
@@ -276,12 +343,11 @@ ensure_range (unsigned int start,
|
||||
|
||||
set:
|
||||
if (range->desc)
|
||||
pango2_font_description_free (range->desc);
|
||||
pango_font_description_free (range->desc);
|
||||
if (desc)
|
||||
range->desc = pango2_font_description_copy (desc);
|
||||
range->desc = pango_font_description_copy (desc);
|
||||
g_free (range->features);
|
||||
range->features = g_strdup (features);
|
||||
range->palette = g_strdup (palette);
|
||||
range->language = language;
|
||||
}
|
||||
|
||||
@@ -478,22 +544,19 @@ update_display (void)
|
||||
GString *s;
|
||||
char *text;
|
||||
gboolean has_feature;
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel *model;
|
||||
Pango2FontDescription *desc;
|
||||
PangoFontDescription *desc;
|
||||
GList *l;
|
||||
Pango2AttrList *attrs;
|
||||
Pango2Attribute *attr;
|
||||
PangoAttrList *attrs;
|
||||
PangoAttribute *attr;
|
||||
int ins, bound;
|
||||
guint start, end;
|
||||
Pango2Language *lang;
|
||||
PangoLanguage *lang;
|
||||
char *font_desc;
|
||||
char *features;
|
||||
double value;
|
||||
int text_len;
|
||||
gboolean do_waterfall;
|
||||
GString *waterfall;
|
||||
char *palette;
|
||||
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
@@ -511,8 +574,8 @@ update_display (void)
|
||||
|
||||
if (do_waterfall)
|
||||
{
|
||||
start = PANGO2_ATTR_INDEX_FROM_TEXT_BEGINNING;
|
||||
end = PANGO2_ATTR_INDEX_TO_TEXT_END;
|
||||
start = PANGO_ATTR_INDEX_FROM_TEXT_BEGINNING;
|
||||
end = PANGO_ATTR_INDEX_TO_TEXT_END;
|
||||
}
|
||||
else if (gtk_label_get_selection_bounds (GTK_LABEL (demo->the_label), &ins, &bound))
|
||||
{
|
||||
@@ -521,24 +584,24 @@ update_display (void)
|
||||
}
|
||||
else
|
||||
{
|
||||
start = PANGO2_ATTR_INDEX_FROM_TEXT_BEGINNING;
|
||||
end = PANGO2_ATTR_INDEX_TO_TEXT_END;
|
||||
start = PANGO_ATTR_INDEX_FROM_TEXT_BEGINNING;
|
||||
end = PANGO_ATTR_INDEX_TO_TEXT_END;
|
||||
}
|
||||
|
||||
desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (demo->font));
|
||||
|
||||
value = gtk_adjustment_get_value (demo->size_adjustment);
|
||||
pango2_font_description_set_size (desc, value * PANGO2_SCALE);
|
||||
pango_font_description_set_size (desc, value * PANGO_SCALE);
|
||||
|
||||
s = g_string_new ("");
|
||||
add_font_variations (s);
|
||||
if (s->len > 0)
|
||||
{
|
||||
pango2_font_description_set_variations (desc, s->str);
|
||||
pango_font_description_set_variations (desc, s->str);
|
||||
g_string_free (s, TRUE);
|
||||
}
|
||||
|
||||
font_desc = pango2_font_description_to_string (desc);
|
||||
font_desc = pango_font_description_to_string (desc);
|
||||
|
||||
s = g_string_new ("");
|
||||
|
||||
@@ -583,34 +646,33 @@ update_display (void)
|
||||
|
||||
features = g_string_free (s, FALSE);
|
||||
|
||||
palette = g_strdup_printf ("palette%d", demo->palette);
|
||||
|
||||
if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (demo->script_lang), &iter))
|
||||
if (gtk_drop_down_get_selected (GTK_DROP_DOWN (demo->script_lang)) != 0)
|
||||
{
|
||||
hb_tag_t lang_tag;
|
||||
ScriptLang *selected;
|
||||
|
||||
model = gtk_combo_box_get_model (GTK_COMBO_BOX (demo->script_lang));
|
||||
gtk_tree_model_get (model, &iter, 3, &lang_tag, -1);
|
||||
selected = gtk_drop_down_get_selected_item (GTK_DROP_DOWN (demo->script_lang));
|
||||
|
||||
lang = pango2_language_from_string (hb_language_to_string (hb_ot_tag_to_language (lang_tag)));
|
||||
lang = pango_language_from_string (hb_language_to_string (hb_ot_tag_to_language (selected->lang_tag)));
|
||||
}
|
||||
else
|
||||
lang = NULL;
|
||||
|
||||
attrs = pango2_attr_list_new ();
|
||||
attrs = pango_attr_list_new ();
|
||||
|
||||
if (gtk_adjustment_get_value (demo->letterspacing_adjustment) != 0.)
|
||||
{
|
||||
attr = pango2_attr_letter_spacing_new (gtk_adjustment_get_value (demo->letterspacing_adjustment));
|
||||
pango2_attribute_set_range (attr, start, end);
|
||||
pango2_attr_list_insert (attrs, attr);
|
||||
attr = pango_attr_letter_spacing_new (gtk_adjustment_get_value (demo->letterspacing_adjustment));
|
||||
attr->start_index = start;
|
||||
attr->end_index = end;
|
||||
pango_attr_list_insert (attrs, attr);
|
||||
}
|
||||
|
||||
if (gtk_adjustment_get_value (demo->line_height_adjustment) != 1.)
|
||||
{
|
||||
attr = pango2_attr_line_height_new (gtk_adjustment_get_value (demo->line_height_adjustment));
|
||||
pango2_attribute_set_range (attr, start, end);
|
||||
pango2_attr_list_insert (attrs, attr);
|
||||
attr = pango_attr_line_height_new (gtk_adjustment_get_value (demo->line_height_adjustment));
|
||||
attr->start_index = start;
|
||||
attr->end_index = end;
|
||||
pango_attr_list_insert (attrs, attr);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -618,12 +680,16 @@ update_display (void)
|
||||
char *fg, *bg, *css;
|
||||
|
||||
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (demo->foreground), &rgba);
|
||||
attr = pango2_attr_foreground_new (&(Pango2Color){ 65535 * rgba.red,
|
||||
65535 * rgba.green,
|
||||
65535 * rgba.blue,
|
||||
65535 * rgba.alpha });
|
||||
pango2_attribute_set_range (attr, start, end);
|
||||
pango2_attr_list_insert (attrs, attr);
|
||||
attr = pango_attr_foreground_new (65535 * rgba.red,
|
||||
65535 * rgba.green,
|
||||
65535 * rgba.blue);
|
||||
attr->start_index = start;
|
||||
attr->end_index = end;
|
||||
pango_attr_list_insert (attrs, attr);
|
||||
attr = pango_attr_foreground_alpha_new (65535 * rgba.alpha);
|
||||
attr->start_index = start;
|
||||
attr->end_index = end;
|
||||
pango_attr_list_insert (attrs, attr);
|
||||
|
||||
fg = gdk_rgba_to_string (&rgba);
|
||||
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (demo->background), &rgba);
|
||||
@@ -637,40 +703,37 @@ update_display (void)
|
||||
|
||||
if (do_waterfall)
|
||||
{
|
||||
attr = pango2_attr_font_desc_new (desc);
|
||||
pango2_attr_list_insert (attrs, attr);
|
||||
attr = pango2_attr_font_features_new (features);
|
||||
pango2_attr_list_insert (attrs, attr);
|
||||
attr = pango2_attr_palette_new (palette);
|
||||
pango2_attr_list_insert (attrs, attr);
|
||||
attr = pango2_attr_language_new (lang);
|
||||
pango2_attr_list_insert (attrs, attr);
|
||||
attr = pango_attr_font_desc_new (desc);
|
||||
pango_attr_list_insert (attrs, attr);
|
||||
attr = pango_attr_font_features_new (features);
|
||||
pango_attr_list_insert (attrs, attr);
|
||||
attr = pango_attr_language_new (lang);
|
||||
pango_attr_list_insert (attrs, attr);
|
||||
}
|
||||
else
|
||||
{
|
||||
ensure_range (start, end, desc, features, palette, lang);
|
||||
ensure_range (start, end, desc, features, lang);
|
||||
|
||||
for (l = demo->ranges; l; l = l->next)
|
||||
{
|
||||
Range *range = l->data;
|
||||
|
||||
attr = pango2_attr_font_desc_new (range->desc);
|
||||
pango2_attribute_set_range (attr, range->start, range->end);
|
||||
pango2_attr_list_insert (attrs, attr);
|
||||
attr = pango_attr_font_desc_new (range->desc);
|
||||
attr->start_index = range->start;
|
||||
attr->end_index = range->end;
|
||||
pango_attr_list_insert (attrs, attr);
|
||||
|
||||
attr = pango2_attr_font_features_new (range->features);
|
||||
pango2_attribute_set_range (attr, range->start, range->end);
|
||||
pango2_attr_list_insert (attrs, attr);
|
||||
|
||||
attr = pango2_attr_palette_new (range->palette);
|
||||
pango2_attribute_set_range (attr, range->start, range->end);
|
||||
pango2_attr_list_insert (attrs, attr);
|
||||
attr = pango_attr_font_features_new (range->features);
|
||||
attr->start_index = range->start;
|
||||
attr->end_index = range->end;
|
||||
pango_attr_list_insert (attrs, attr);
|
||||
|
||||
if (range->language)
|
||||
{
|
||||
attr = pango2_attr_language_new (range->language);
|
||||
pango2_attribute_set_range (attr, range->start, range->end);
|
||||
pango2_attr_list_insert (attrs, attr);
|
||||
attr = pango_attr_language_new (range->language);
|
||||
attr->start_index = range->start;
|
||||
attr->end_index = range->end;
|
||||
pango_attr_list_insert (attrs, attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -686,13 +749,14 @@ update_display (void)
|
||||
for (int i = 0; i < G_N_ELEMENTS (sizes); i++)
|
||||
{
|
||||
g_string_append (waterfall, text);
|
||||
g_string_append (waterfall, "
"); /* Unicode line separator */
|
||||
g_string_append_c (waterfall, '\n');
|
||||
|
||||
attr = pango2_attr_size_new (sizes[i] * PANGO2_SCALE);
|
||||
pango2_attribute_set_range (attr, start, start + text_len);
|
||||
pango2_attr_list_insert (attrs, attr);
|
||||
attr = pango_attr_size_new (sizes[i] * PANGO_SCALE);
|
||||
attr->start_index = start;
|
||||
attr->end_index = start + text_len;
|
||||
pango_attr_list_insert (attrs, attr);
|
||||
|
||||
start += text_len + strlen ("
");
|
||||
start += text_len + 1;
|
||||
}
|
||||
gtk_label_set_text (GTK_LABEL (demo->the_label), waterfall->str);
|
||||
g_string_free (waterfall, TRUE);
|
||||
@@ -703,23 +767,22 @@ update_display (void)
|
||||
gtk_label_set_attributes (GTK_LABEL (demo->the_label), attrs);
|
||||
|
||||
g_free (font_desc);
|
||||
pango2_font_description_free (desc);
|
||||
pango_font_description_free (desc);
|
||||
g_free (features);
|
||||
g_free (palette);
|
||||
pango2_attr_list_unref (attrs);
|
||||
pango_attr_list_unref (attrs);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
static Pango2Font *
|
||||
static PangoFont *
|
||||
get_pango_font (void)
|
||||
{
|
||||
Pango2FontDescription *desc;
|
||||
Pango2Context *context;
|
||||
PangoFontDescription *desc;
|
||||
PangoContext *context;
|
||||
|
||||
desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (demo->font));
|
||||
context = gtk_widget_get_pango_context (demo->font);
|
||||
|
||||
return pango2_context_load_font (context, desc);
|
||||
return pango_context_load_font (context, desc);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
@@ -746,40 +809,30 @@ tag_pair_equal (gconstpointer a, gconstpointer b)
|
||||
return pair_a->script_tag == pair_b->script_tag && pair_a->lang_tag == pair_b->lang_tag;
|
||||
}
|
||||
|
||||
static int
|
||||
script_sort_func (GtkTreeModel *model,
|
||||
GtkTreeIter *a,
|
||||
GtkTreeIter *b,
|
||||
gpointer user_data)
|
||||
|
||||
static GtkOrdering
|
||||
script_sort (const void *item1,
|
||||
const void *item2,
|
||||
void *data)
|
||||
{
|
||||
char *sa, *sb;
|
||||
int ret;
|
||||
ScriptLang *a = (ScriptLang *)item1;
|
||||
ScriptLang *b = (ScriptLang *)item2;
|
||||
|
||||
gtk_tree_model_get (model, a, 0, &sa, -1);
|
||||
gtk_tree_model_get (model, b, 0, &sb, -1);
|
||||
|
||||
ret = strcmp (sa, sb);
|
||||
|
||||
g_free (sa);
|
||||
g_free (sb);
|
||||
|
||||
return ret;
|
||||
return strcmp (a->langname, b->langname);
|
||||
}
|
||||
|
||||
static void
|
||||
update_script_combo (void)
|
||||
{
|
||||
GtkListStore *store;
|
||||
GListStore *store;
|
||||
GtkSortListModel *sortmodel;
|
||||
hb_font_t *hb_font;
|
||||
int i, j, k;
|
||||
Pango2Font *pango_font;
|
||||
PangoFont *pango_font;
|
||||
GHashTable *tags;
|
||||
GHashTableIter iter;
|
||||
TagPair *pair;
|
||||
char *lang;
|
||||
hb_tag_t active;
|
||||
GtkTreeIter active_iter;
|
||||
gboolean have_active = FALSE;
|
||||
|
||||
lang = gtk_font_chooser_get_language (GTK_FONT_CHOOSER (demo->font));
|
||||
|
||||
@@ -789,10 +842,10 @@ update_script_combo (void)
|
||||
|
||||
g_free (lang);
|
||||
|
||||
store = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
|
||||
store = g_list_store_new (script_lang_get_type ());
|
||||
|
||||
pango_font = get_pango_font ();
|
||||
hb_font = pango2_font_get_hb_font (pango_font);
|
||||
hb_font = pango_font_get_hb_font (pango_font);
|
||||
|
||||
tags = g_hash_table_new_full (tag_pair_hash, tag_pair_equal, g_free, NULL);
|
||||
|
||||
@@ -813,19 +866,19 @@ update_script_combo (void)
|
||||
|
||||
hb_face = hb_font_get_face (hb_font);
|
||||
|
||||
for (i= 0; i < 2; i++)
|
||||
for (guint i = 0; i < 2; i++)
|
||||
{
|
||||
hb_tag_t scripts[80];
|
||||
unsigned int script_count = G_N_ELEMENTS (scripts);
|
||||
|
||||
hb_ot_layout_table_get_script_tags (hb_face, tables[i], 0, &script_count, scripts);
|
||||
for (j = 0; j < script_count; j++)
|
||||
for (guint j = 0; j < script_count; j++)
|
||||
{
|
||||
hb_tag_t languages[80];
|
||||
unsigned int language_count = G_N_ELEMENTS (languages);
|
||||
|
||||
hb_ot_layout_script_get_language_tags (hb_face, tables[i], j, 0, &language_count, languages);
|
||||
for (k = 0; k < language_count; k++)
|
||||
for (guint k = 0; k < language_count; k++)
|
||||
{
|
||||
pair = g_new (TagPair, 1);
|
||||
pair->script_tag = scripts[j];
|
||||
@@ -845,7 +898,6 @@ update_script_combo (void)
|
||||
{
|
||||
const char *langname;
|
||||
char langbuf[5];
|
||||
GtkTreeIter tree_iter;
|
||||
|
||||
if (pair->lang_tag == 0 && pair->script_tag == 0)
|
||||
langname = NC_("Language", "None");
|
||||
@@ -862,31 +914,31 @@ update_script_combo (void)
|
||||
}
|
||||
}
|
||||
|
||||
gtk_list_store_insert_with_values (store, &tree_iter, -1,
|
||||
0, langname,
|
||||
1, pair->script_index,
|
||||
2, pair->lang_index,
|
||||
3, pair->lang_tag,
|
||||
-1);
|
||||
if (pair->lang_tag == active)
|
||||
{
|
||||
have_active = TRUE;
|
||||
active_iter = tree_iter;
|
||||
}
|
||||
g_list_store_append (store, script_lang_new (langname,
|
||||
pair->script_index,
|
||||
pair->lang_index,
|
||||
pair->lang_tag));
|
||||
}
|
||||
|
||||
g_hash_table_destroy (tags);
|
||||
|
||||
gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (store),
|
||||
script_sort_func, NULL, NULL);
|
||||
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
|
||||
GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
|
||||
GTK_SORT_ASCENDING);
|
||||
gtk_combo_box_set_model (GTK_COMBO_BOX (demo->script_lang), GTK_TREE_MODEL (store));
|
||||
if (have_active)
|
||||
gtk_combo_box_set_active_iter (GTK_COMBO_BOX (demo->script_lang), &active_iter);
|
||||
else
|
||||
gtk_combo_box_set_active_iter (GTK_COMBO_BOX (demo->script_lang), 0);
|
||||
sortmodel = gtk_sort_list_model_new (G_LIST_MODEL (store),
|
||||
GTK_SORTER (gtk_custom_sorter_new (script_sort, NULL, NULL)));
|
||||
gtk_drop_down_set_model (GTK_DROP_DOWN (demo->script_lang), G_LIST_MODEL (sortmodel));
|
||||
|
||||
for (guint i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (sortmodel)); i++)
|
||||
{
|
||||
ScriptLang *item = g_list_model_get_item (G_LIST_MODEL (sortmodel), i);
|
||||
g_object_unref (item);
|
||||
|
||||
if (item->lang_tag == active)
|
||||
{
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (demo->script_lang), i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (sortmodel);
|
||||
}
|
||||
|
||||
static char *
|
||||
@@ -911,27 +963,19 @@ static void
|
||||
update_features (void)
|
||||
{
|
||||
int i, j;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
guint script_index, lang_index;
|
||||
hb_tag_t lang_tag;
|
||||
Pango2Font *pango_font;
|
||||
PangoFont *pango_font;
|
||||
hb_font_t *hb_font;
|
||||
GList *l;
|
||||
ScriptLang *selected;
|
||||
|
||||
/* set feature presence checks from the font features */
|
||||
|
||||
if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (demo->script_lang), &iter))
|
||||
if (gtk_drop_down_get_selected (GTK_DROP_DOWN (demo->script_lang)) == 0)
|
||||
return;
|
||||
|
||||
model = gtk_combo_box_get_model (GTK_COMBO_BOX (demo->script_lang));
|
||||
gtk_tree_model_get (model, &iter,
|
||||
1, &script_index,
|
||||
2, &lang_index,
|
||||
3, &lang_tag,
|
||||
-1);
|
||||
selected = gtk_drop_down_get_selected_item (GTK_DROP_DOWN (demo->script_lang));
|
||||
|
||||
if (lang_tag == 0) /* None is selected */
|
||||
if (selected->lang_tag == 0) /* None is selected */
|
||||
{
|
||||
for (l = demo->feature_items; l; l = l->next)
|
||||
{
|
||||
@@ -954,19 +998,8 @@ update_features (void)
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (item->feat), TRUE);
|
||||
}
|
||||
|
||||
/* set feature presence checks from the font features */
|
||||
|
||||
if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (demo->script_lang), &iter))
|
||||
return;
|
||||
|
||||
model = gtk_combo_box_get_model (GTK_COMBO_BOX (demo->script_lang));
|
||||
gtk_tree_model_get (model, &iter,
|
||||
1, &script_index,
|
||||
2, &lang_index,
|
||||
-1);
|
||||
|
||||
pango_font = get_pango_font ();
|
||||
hb_font = pango2_font_get_hb_font (pango_font);
|
||||
hb_font = pango_font_get_hb_font (pango_font);
|
||||
|
||||
if (hb_font)
|
||||
{
|
||||
@@ -983,8 +1016,8 @@ update_features (void)
|
||||
|
||||
hb_ot_layout_language_get_feature_tags (hb_face,
|
||||
tables[i],
|
||||
script_index,
|
||||
lang_index,
|
||||
selected->script_index,
|
||||
selected->lang_index,
|
||||
0,
|
||||
&count,
|
||||
features);
|
||||
@@ -1006,8 +1039,8 @@ update_features (void)
|
||||
|
||||
hb_ot_layout_language_find_feature (hb_face,
|
||||
tables[i],
|
||||
script_index,
|
||||
lang_index,
|
||||
selected->script_index,
|
||||
selected->lang_index,
|
||||
features[j],
|
||||
&feature_index);
|
||||
|
||||
@@ -1194,8 +1227,6 @@ ease_out_cubic (double t)
|
||||
return p * p * p + 1;
|
||||
}
|
||||
|
||||
static const guint64 period = G_TIME_SPAN_SECOND * 3;
|
||||
|
||||
static gboolean
|
||||
animate_axis (GtkWidget *widget,
|
||||
GdkFrameClock *frame_clock,
|
||||
@@ -1207,13 +1238,13 @@ animate_axis (GtkWidget *widget,
|
||||
|
||||
now = g_get_monotonic_time ();
|
||||
|
||||
if (now >= axis->start_time + period)
|
||||
if (now >= axis->start_time + G_TIME_SPAN_SECOND)
|
||||
{
|
||||
axis->start_time += period;
|
||||
axis->start_time += G_TIME_SPAN_SECOND;
|
||||
axis->increasing = !axis->increasing;
|
||||
}
|
||||
|
||||
value = (now - axis->start_time) / (double) period;
|
||||
value = (now - axis->start_time) / (double) G_TIME_SPAN_SECOND;
|
||||
|
||||
value = ease_out_cubic (value);
|
||||
|
||||
@@ -1250,7 +1281,7 @@ start_or_stop_axis_animation (GtkButton *button,
|
||||
lower = gtk_adjustment_get_lower (axis->adjustment);
|
||||
upper = gtk_adjustment_get_upper (axis->adjustment);
|
||||
value = value / (upper - lower);
|
||||
axis->start_time = g_get_monotonic_time () - value * period;
|
||||
axis->start_time = g_get_monotonic_time () - value * G_TIME_SPAN_SECOND;
|
||||
axis->increasing = TRUE;
|
||||
}
|
||||
}
|
||||
@@ -1341,10 +1372,9 @@ free_instance (gpointer data)
|
||||
}
|
||||
|
||||
static void
|
||||
add_instance (hb_face_t *face,
|
||||
unsigned int index,
|
||||
GtkWidget *combo,
|
||||
int pos)
|
||||
add_instance (hb_face_t *face,
|
||||
unsigned int index,
|
||||
GtkStringList *strings)
|
||||
{
|
||||
Instance *instance;
|
||||
hb_ot_name_id_t name_id;
|
||||
@@ -1360,20 +1390,20 @@ add_instance (hb_face_t *face,
|
||||
instance->index = index;
|
||||
|
||||
g_hash_table_add (demo->instances, instance);
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), instance->name);
|
||||
gtk_string_list_append (GTK_STRING_LIST (strings), instance->name);
|
||||
}
|
||||
|
||||
static void
|
||||
unset_instance (GtkAdjustment *adjustment)
|
||||
{
|
||||
if (demo->instance_combo)
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (demo->instance_combo), 0);
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (demo->instance_combo), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
instance_changed (GtkComboBox *combo)
|
||||
instance_changed (GtkDropDown *combo)
|
||||
{
|
||||
char *text;
|
||||
const char *text;
|
||||
Instance *instance;
|
||||
Instance ikey;
|
||||
int i;
|
||||
@@ -1381,15 +1411,16 @@ instance_changed (GtkComboBox *combo)
|
||||
float *coords = NULL;
|
||||
hb_ot_var_axis_info_t *ai = NULL;
|
||||
unsigned int n_axes;
|
||||
Pango2Font *pango_font = NULL;
|
||||
PangoFont *pango_font = NULL;
|
||||
hb_font_t *hb_font;
|
||||
hb_face_t *hb_face;
|
||||
|
||||
text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (combo));
|
||||
text = gtk_string_list_get_string (GTK_STRING_LIST (gtk_drop_down_get_model (combo)),
|
||||
gtk_drop_down_get_selected (combo));
|
||||
if (text[0] == '\0')
|
||||
goto out;
|
||||
|
||||
ikey.name = text;
|
||||
ikey.name = (char *) text;
|
||||
instance = g_hash_table_lookup (demo->instances, &ikey);
|
||||
if (!instance)
|
||||
{
|
||||
@@ -1398,7 +1429,7 @@ instance_changed (GtkComboBox *combo)
|
||||
}
|
||||
|
||||
pango_font = get_pango_font ();
|
||||
hb_font = pango2_font_get_hb_font (pango_font);
|
||||
hb_font = pango_font_get_hb_font (pango_font);
|
||||
hb_face = hb_font_get_face (hb_font);
|
||||
|
||||
n_axes = hb_ot_var_get_axis_infos (hb_face, 0, NULL, NULL);
|
||||
@@ -1430,7 +1461,6 @@ instance_changed (GtkComboBox *combo)
|
||||
}
|
||||
|
||||
out:
|
||||
g_free (text);
|
||||
g_clear_object (&pango_font);
|
||||
g_free (ai);
|
||||
g_free (coords);
|
||||
@@ -1499,10 +1529,10 @@ denorm_coord (hb_ot_var_axis_info_t *axis, int coord)
|
||||
}
|
||||
|
||||
static void
|
||||
update_variations (void)
|
||||
update_font_variations (void)
|
||||
{
|
||||
GtkWidget *child;
|
||||
Pango2Font *pango_font = NULL;
|
||||
PangoFont *pango_font = NULL;
|
||||
hb_font_t *hb_font;
|
||||
hb_face_t *hb_face;
|
||||
unsigned int n_axes;
|
||||
@@ -1521,7 +1551,7 @@ update_variations (void)
|
||||
g_hash_table_remove_all (demo->instances);
|
||||
|
||||
pango_font = get_pango_font ();
|
||||
hb_font = pango2_font_get_hb_font (pango_font);
|
||||
hb_font = pango_font_get_hb_font (pango_font);
|
||||
hb_face = hb_font_get_face (hb_font);
|
||||
|
||||
n_axes = hb_ot_var_get_axis_infos (hb_face, 0, NULL, NULL);
|
||||
@@ -1540,6 +1570,7 @@ update_variations (void)
|
||||
{
|
||||
GtkWidget *label;
|
||||
GtkWidget *combo;
|
||||
GtkStringList *strings;
|
||||
|
||||
label = gtk_label_new ("Instance");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
@@ -1547,26 +1578,28 @@ update_variations (void)
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
|
||||
gtk_grid_attach (GTK_GRID (demo->variations_grid), label, 0, -1, 1, 1);
|
||||
|
||||
combo = gtk_combo_box_text_new ();
|
||||
strings = gtk_string_list_new (NULL);
|
||||
combo = gtk_drop_down_new (G_LIST_MODEL (strings), NULL);
|
||||
|
||||
gtk_widget_set_halign (combo, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (combo, GTK_ALIGN_BASELINE);
|
||||
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "");
|
||||
gtk_string_list_append (strings, "");
|
||||
|
||||
for (i = 0; i < hb_ot_var_get_named_instance_count (hb_face); i++)
|
||||
add_instance (hb_face, i, combo, i);
|
||||
add_instance (hb_face, i, strings);
|
||||
|
||||
for (i = 0; i < hb_ot_var_get_named_instance_count (hb_face); i++)
|
||||
{
|
||||
if (matches_instance (hb_face, i, n_axes, design_coords))
|
||||
{
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), i + 1);
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (combo), i + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gtk_grid_attach (GTK_GRID (demo->variations_grid), combo, 1, -1, 3, 1);
|
||||
g_signal_connect (combo, "changed", G_CALLBACK (instance_changed), NULL);
|
||||
g_signal_connect (combo, "notify::selecte", G_CALLBACK (instance_changed), NULL);
|
||||
demo->instance_combo = combo;
|
||||
}
|
||||
|
||||
@@ -1581,125 +1614,13 @@ done:
|
||||
g_free (design_coords);
|
||||
}
|
||||
|
||||
static void
|
||||
palette_changed (GtkCheckButton *button)
|
||||
{
|
||||
demo->palette = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (button), "palette"));
|
||||
update_display ();
|
||||
}
|
||||
|
||||
static void
|
||||
update_colors (void)
|
||||
{
|
||||
Pango2Font *pango_font = NULL;
|
||||
hb_font_t *hb_font;
|
||||
hb_face_t *hb_face;
|
||||
GtkWidget *child;
|
||||
|
||||
while ((child = gtk_widget_get_first_child (demo->colors_grid)))
|
||||
gtk_grid_remove (GTK_GRID (demo->colors_grid), child);
|
||||
|
||||
pango_font = get_pango_font ();
|
||||
hb_font = pango2_font_get_hb_font (pango_font);
|
||||
hb_face = hb_font_get_face (hb_font);
|
||||
|
||||
if (hb_ot_color_has_palettes (hb_face))
|
||||
{
|
||||
demo->first_palette = NULL;
|
||||
|
||||
for (unsigned int i = 0; i < hb_ot_color_palette_get_count (hb_face); i++)
|
||||
{
|
||||
hb_ot_name_id_t name_id;
|
||||
char *name;
|
||||
unsigned int n_colors;
|
||||
hb_color_t *colors;
|
||||
GtkWidget *palette;
|
||||
GtkWidget *swatch;
|
||||
hb_ot_color_palette_flags_t flags;
|
||||
const char *str;
|
||||
GtkWidget *toggle;
|
||||
|
||||
name_id = hb_ot_color_palette_get_name_id (hb_face, i);
|
||||
if (name_id != HB_OT_NAME_ID_INVALID)
|
||||
{
|
||||
unsigned int len;
|
||||
char buf[80];
|
||||
|
||||
len = sizeof (buf);
|
||||
hb_ot_name_get_utf8 (hb_face, name_id, HB_LANGUAGE_INVALID, &len, buf);
|
||||
name = g_strdup (buf);
|
||||
}
|
||||
else
|
||||
name = g_strdup_printf ("Palette %d", i);
|
||||
|
||||
toggle = gtk_check_button_new_with_label (name);
|
||||
if (i == demo->palette)
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (toggle), TRUE);
|
||||
|
||||
g_object_set_data (G_OBJECT (toggle), "palette", GUINT_TO_POINTER (i));
|
||||
g_signal_connect (toggle, "toggled", G_CALLBACK (palette_changed), NULL);
|
||||
|
||||
if (demo->first_palette)
|
||||
gtk_check_button_set_group (GTK_CHECK_BUTTON (toggle), GTK_CHECK_BUTTON (demo->first_palette));
|
||||
else
|
||||
demo->first_palette = toggle;
|
||||
|
||||
g_free (name);
|
||||
|
||||
gtk_grid_attach (GTK_GRID (demo->colors_grid), toggle, 0, i, 1, 1);
|
||||
|
||||
flags = hb_ot_color_palette_get_flags (hb_face, i);
|
||||
if ((flags & (HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_LIGHT_BACKGROUND |
|
||||
HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND)) ==
|
||||
(HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_LIGHT_BACKGROUND |
|
||||
HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND))
|
||||
str = "(light, dark)";
|
||||
else if (flags & HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_LIGHT_BACKGROUND)
|
||||
str = "(light)";
|
||||
else if (flags & HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND)
|
||||
str = "(dark)";
|
||||
else
|
||||
str = NULL;
|
||||
if (str)
|
||||
gtk_grid_attach (GTK_GRID (demo->colors_grid), gtk_label_new (str), 1, i, 1, 1);
|
||||
|
||||
n_colors = hb_ot_color_palette_get_colors (hb_face, i, 0, NULL, NULL);
|
||||
colors = g_new (hb_color_t, n_colors);
|
||||
n_colors = hb_ot_color_palette_get_colors (hb_face, i, 0, &n_colors, colors);
|
||||
|
||||
palette = gtk_grid_new ();
|
||||
gtk_grid_attach (GTK_GRID (demo->colors_grid), palette, 2, i, 1, 1);
|
||||
|
||||
for (int k = 0; k < n_colors; k++)
|
||||
{
|
||||
swatch = g_object_new (g_type_from_name ("GtkColorSwatch"),
|
||||
"rgba", &(GdkRGBA){ hb_color_get_red (colors[k])/255.,
|
||||
hb_color_get_green (colors[k])/255.,
|
||||
hb_color_get_blue (colors[k])/255.,
|
||||
hb_color_get_alpha (colors[k])/255.},
|
||||
"width-request", 16,
|
||||
"height-request", 16,
|
||||
NULL);
|
||||
gtk_grid_attach (GTK_GRID (palette), swatch, k % 8, k / 8, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
font_features_reset_colors (void)
|
||||
{
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (demo->first_palette), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
font_features_font_changed (void)
|
||||
{
|
||||
update_basic ();
|
||||
update_script_combo ();
|
||||
update_features ();
|
||||
update_variations ();
|
||||
update_colors ();
|
||||
update_font_variations ();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1825,6 +1746,7 @@ do_font_features (GtkWidget *do_widget)
|
||||
GtkBuilder *builder;
|
||||
GtkBuilderScope *scope;
|
||||
GtkEventController *controller;
|
||||
GtkExpression *expression;
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
|
||||
@@ -1836,7 +1758,6 @@ do_font_features (GtkWidget *do_widget)
|
||||
gtk_builder_cscope_add_callback (scope, font_features_reset_basic);
|
||||
gtk_builder_cscope_add_callback (scope, font_features_reset_features);
|
||||
gtk_builder_cscope_add_callback (scope, font_features_reset_variations);
|
||||
gtk_builder_cscope_add_callback (scope, font_features_reset_colors);
|
||||
gtk_builder_cscope_add_callback (scope, font_features_toggle_plain);
|
||||
gtk_builder_cscope_add_callback (scope, font_features_toggle_edit);
|
||||
gtk_builder_cscope_add_callback (scope, font_features_stop_edit);
|
||||
@@ -1859,6 +1780,9 @@ do_font_features (GtkWidget *do_widget)
|
||||
demo->description = GTK_WIDGET (gtk_builder_get_object (builder, "description"));
|
||||
demo->font = GTK_WIDGET (gtk_builder_get_object (builder, "font"));
|
||||
demo->script_lang = GTK_WIDGET (gtk_builder_get_object (builder, "script_lang"));
|
||||
expression = gtk_cclosure_expression_new (G_TYPE_STRING, NULL, 0, NULL, G_CALLBACK (script_lang_get_langname), NULL, NULL);
|
||||
gtk_drop_down_set_expression (GTK_DROP_DOWN (demo->script_lang), expression);
|
||||
gtk_expression_unref (expression);
|
||||
demo->feature_list = GTK_WIDGET (gtk_builder_get_object (builder, "feature_list"));
|
||||
demo->stack = GTK_WIDGET (gtk_builder_get_object (builder, "stack"));
|
||||
demo->entry = GTK_WIDGET (gtk_builder_get_object (builder, "entry"));
|
||||
@@ -1875,12 +1799,10 @@ do_font_features (GtkWidget *do_widget)
|
||||
demo->foreground = GTK_WIDGET (gtk_builder_get_object (builder, "foreground"));
|
||||
demo->background = GTK_WIDGET (gtk_builder_get_object (builder, "background"));
|
||||
demo->swin = GTK_WIDGET (gtk_builder_get_object (builder, "swin"));
|
||||
demo->variations_grid = GTK_WIDGET (gtk_builder_get_object (builder, "variations_grid"));
|
||||
demo->colors_grid = GTK_WIDGET (gtk_builder_get_object (builder, "colors_grid"));
|
||||
|
||||
demo->provider = gtk_css_provider_new ();
|
||||
gtk_style_context_add_provider (gtk_widget_get_style_context (demo->swin),
|
||||
GTK_STYLE_PROVIDER (demo->provider), 800);
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (demo->provider), 800);
|
||||
|
||||
basic_value_changed (demo->size_adjustment, demo->size_entry);
|
||||
basic_value_changed (demo->letterspacing_adjustment, demo->letterspacing_entry);
|
||||
@@ -1931,6 +1853,7 @@ do_font_features (GtkWidget *do_widget)
|
||||
(const char *[]){ "opbd", "lfbd", "rtbd", NULL });
|
||||
demo->feature_items = g_list_reverse (demo->feature_items);
|
||||
|
||||
demo->variations_grid = GTK_WIDGET (gtk_builder_get_object (builder, "variations_grid"));
|
||||
if (demo->instances == NULL)
|
||||
demo->instances = g_hash_table_new_full (instance_hash, instance_equal, NULL, free_instance);
|
||||
else
|
||||
@@ -1957,3 +1880,5 @@ do_font_features (GtkWidget *do_widget)
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
/* vim:set foldmethod=marker expandtab: */
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
--- demos/gtk-demo/font_features.c
|
||||
+++ demos/gtk-demo/font_features.c
|
||||
@@ -434,7 +434,7 @@ static void
|
||||
update_display (void)
|
||||
{
|
||||
GString *s;
|
||||
- const char *text;
|
||||
+ char *text;
|
||||
gboolean has_feature;
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel *model;
|
||||
@@ -452,8 +452,12 @@ update_display (void)
|
||||
gboolean do_waterfall;
|
||||
GString *waterfall;
|
||||
char *palette;
|
||||
+ GtkTextBuffer *buffer;
|
||||
+ GtkTextIter start_iter, end_iter;
|
||||
|
||||
- text = gtk_editable_get_text (GTK_EDITABLE (demo->the_entry));
|
||||
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (demo->the_entry));
|
||||
+ gtk_text_buffer_get_bounds (buffer, &start_iter, &end_iter);
|
||||
+ text = gtk_text_buffer_get_text (buffer, &start_iter, &end_iter, FALSE);
|
||||
text_len = strlen (text);
|
||||
|
||||
do_waterfall = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (demo->waterfall_toggle));
|
||||
@@ -631,6 +635,8 @@ update_display (void)
|
||||
pango2_font_description_free (desc);
|
||||
g_free (features);
|
||||
pango2_attr_list_unref (attrs);
|
||||
+
|
||||
+ g_free (text);
|
||||
}
|
||||
|
||||
static Pango2Font *
|
||||
@@ -1603,8 +1609,12 @@ font_features_toggle_edit (void)
|
||||
{
|
||||
if (strcmp (gtk_stack_get_visible_child_name (GTK_STACK (demo->stack)), "entry") != 0)
|
||||
{
|
||||
+ GtkTextBuffer *buffer;
|
||||
+ GtkTextIter start, end;
|
||||
g_free (demo->text);
|
||||
- demo->text = g_strdup (gtk_editable_get_text (GTK_EDITABLE (demo->the_entry)));
|
||||
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (demo->the_entry));
|
||||
+ gtk_text_buffer_get_bounds (buffer, &start, &end);
|
||||
+ demo->text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (demo->stack), "entry");
|
||||
gtk_widget_grab_focus (demo->the_entry);
|
||||
gtk_adjustment_set_value (gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (demo->swin)), 0);
|
||||
@@ -1632,7 +1642,7 @@ entry_key_press (GtkEventController *controller,
|
||||
{
|
||||
if (keyval == GDK_KEY_Escape)
|
||||
{
|
||||
- gtk_editable_set_text (GTK_EDITABLE (entry), demo->text);
|
||||
+ gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (demo->the_entry)), demo->text, -1);
|
||||
return GDK_EVENT_STOP;
|
||||
}
|
||||
|
||||
@@ -1701,7 +1711,6 @@ do_font_features (GtkWidget *do_widget)
|
||||
basic_value_changed (demo->line_height_adjustment, demo->line_height_entry);
|
||||
|
||||
controller = gtk_event_controller_key_new ();
|
||||
- g_object_set_data_full (G_OBJECT (demo->the_entry), "controller", g_object_ref (controller), g_object_unref);
|
||||
g_signal_connect (controller, "key-pressed", G_CALLBACK (entry_key_press), demo->the_entry);
|
||||
gtk_widget_add_controller (demo->the_entry, controller);
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
<signal name="clicked" handler="font_features_reset_basic" swapped="no"/>
|
||||
<signal name="clicked" handler="font_features_reset_features" swapped="no"/>
|
||||
<signal name="clicked" handler="font_features_reset_variations" swapped="no"/>
|
||||
<signal name="clicked" handler="font_features_reset_colors" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -260,16 +259,10 @@
|
||||
<object class="GtkBox" id="feature_list">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="script_lang">
|
||||
<object class="GtkDropDown" id="script_lang">
|
||||
<property name="tooltip-text" translatable="yes">Language System</property>
|
||||
<property name="margin-top">10</property>
|
||||
<signal name="changed" handler="font_features_script_changed" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
<signal name="notify::selected" handler="font_features_script_changed" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -297,27 +290,6 @@
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkExpander">
|
||||
<child type="label">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Color Palettes</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="margin-top">10</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<style>
|
||||
<class name="title-4"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGrid" id="colors_grid">
|
||||
<property name="column-spacing">10</property>
|
||||
<property name="row-spacing">10</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
static void
|
||||
insert_tags_for_attributes (GtkTextBuffer *buffer,
|
||||
Pango2AttrIterator *iter,
|
||||
PangoAttrIterator *iter,
|
||||
GtkTextIter *start,
|
||||
GtkTextIter *end)
|
||||
{
|
||||
@@ -27,12 +27,13 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
|
||||
GSList *attrs, *l;
|
||||
GtkTextTag *tag;
|
||||
char name[256];
|
||||
float fg_alpha, bg_alpha;
|
||||
|
||||
table = gtk_text_buffer_get_tag_table (buffer);
|
||||
|
||||
#define LANGUAGE_ATTR(attr_name) \
|
||||
{ \
|
||||
const char *language = pango2_language_to_string (pango2_attribute_get_language (attr)); \
|
||||
const char *language = pango_language_to_string (((PangoAttrLanguage*)attr)->value); \
|
||||
g_snprintf (name, 256, "language=%s", language); \
|
||||
tag = gtk_text_tag_table_lookup (table, name); \
|
||||
if (!tag) \
|
||||
@@ -47,7 +48,7 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
|
||||
|
||||
#define STRING_ATTR(attr_name) \
|
||||
{ \
|
||||
const char *string = pango2_attribute_get_string (attr); \
|
||||
const char *string = ((PangoAttrString*)attr)->value; \
|
||||
g_snprintf (name, 256, #attr_name "=%s", string); \
|
||||
tag = gtk_text_tag_table_lookup (table, name); \
|
||||
if (!tag) \
|
||||
@@ -62,7 +63,7 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
|
||||
|
||||
#define INT_ATTR(attr_name) \
|
||||
{ \
|
||||
int value = pango2_attribute_get_int (attr); \
|
||||
int value = ((PangoAttrInt*)attr)->value; \
|
||||
g_snprintf (name, 256, #attr_name "=%d", value); \
|
||||
tag = gtk_text_tag_table_lookup (table, name); \
|
||||
if (!tag) \
|
||||
@@ -77,8 +78,8 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
|
||||
|
||||
#define FONT_ATTR(attr_name) \
|
||||
{ \
|
||||
Pango2FontDescription *desc = pango2_attribute_get_font_desc (attr); \
|
||||
char *str = pango2_font_description_to_string (desc); \
|
||||
PangoFontDescription *desc = ((PangoAttrFontDesc*)attr)->desc; \
|
||||
char *str = pango_font_description_to_string (desc); \
|
||||
g_snprintf (name, 256, "font-desc=%s", str); \
|
||||
g_free (str); \
|
||||
tag = gtk_text_tag_table_lookup (table, name); \
|
||||
@@ -94,7 +95,7 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
|
||||
|
||||
#define FLOAT_ATTR(attr_name) \
|
||||
{ \
|
||||
float value = pango2_attribute_get_float (attr); \
|
||||
float value = ((PangoAttrFloat*)attr)->value; \
|
||||
g_snprintf (name, 256, #attr_name "=%g", value); \
|
||||
tag = gtk_text_tag_table_lookup (table, name); \
|
||||
if (!tag) \
|
||||
@@ -107,14 +108,15 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
|
||||
gtk_text_buffer_apply_tag (buffer, tag, start, end); \
|
||||
}
|
||||
|
||||
#define RGBA_ATTR(attr_name) \
|
||||
#define RGBA_ATTR(attr_name, alpha_value) \
|
||||
{ \
|
||||
Pango2Color *color = pango2_attribute_get_color (attr); \
|
||||
PangoColor *color; \
|
||||
GdkRGBA rgba; \
|
||||
color = &((PangoAttrColor*)attr)->color; \
|
||||
rgba.red = color->red / 65535.; \
|
||||
rgba.green = color->green / 65535.; \
|
||||
rgba.blue = color->blue / 65535.; \
|
||||
rgba.alpha = color->alpha / 65535.; \
|
||||
rgba.alpha = alpha_value; \
|
||||
char *str = gdk_rgba_to_string (&rgba); \
|
||||
g_snprintf (name, 256, #attr_name "=%s", str); \
|
||||
g_free (str); \
|
||||
@@ -142,157 +144,173 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
|
||||
gtk_text_buffer_apply_tag (buffer, tag, start, end); \
|
||||
}
|
||||
|
||||
attrs = pango2_attr_iterator_get_attrs (iter);
|
||||
fg_alpha = bg_alpha = 1.;
|
||||
|
||||
attrs = pango_attr_iterator_get_attrs (iter);
|
||||
for (l = attrs; l; l = l->next)
|
||||
{
|
||||
Pango2Attribute *attr = l->data;
|
||||
PangoAttribute *attr = l->data;
|
||||
|
||||
switch (pango2_attribute_type (attr))
|
||||
switch ((int)attr->klass->type)
|
||||
{
|
||||
case PANGO2_ATTR_LANGUAGE:
|
||||
case PANGO_ATTR_FOREGROUND_ALPHA:
|
||||
fg_alpha = ((PangoAttrInt*)attr)->value / 65535.;
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_BACKGROUND_ALPHA:
|
||||
bg_alpha = ((PangoAttrInt*)attr)->value / 65535.;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (l = attrs; l; l = l->next)
|
||||
{
|
||||
PangoAttribute *attr = l->data;
|
||||
|
||||
switch (attr->klass->type)
|
||||
{
|
||||
case PANGO_ATTR_LANGUAGE:
|
||||
LANGUAGE_ATTR (language);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_FAMILY:
|
||||
case PANGO_ATTR_FAMILY:
|
||||
STRING_ATTR (family);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_STYLE:
|
||||
case PANGO_ATTR_STYLE:
|
||||
INT_ATTR (style);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_WEIGHT:
|
||||
case PANGO_ATTR_WEIGHT:
|
||||
INT_ATTR (weight);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_VARIANT:
|
||||
case PANGO_ATTR_VARIANT:
|
||||
INT_ATTR (variant);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_STRETCH:
|
||||
case PANGO_ATTR_STRETCH:
|
||||
INT_ATTR (stretch);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_SIZE:
|
||||
case PANGO_ATTR_SIZE:
|
||||
INT_ATTR (size);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_FONT_DESC:
|
||||
case PANGO_ATTR_FONT_DESC:
|
||||
FONT_ATTR (font-desc);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_FOREGROUND:
|
||||
RGBA_ATTR (foreground_rgba);
|
||||
case PANGO_ATTR_FOREGROUND:
|
||||
RGBA_ATTR (foreground_rgba, fg_alpha);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_BACKGROUND:
|
||||
RGBA_ATTR (background_rgba);
|
||||
case PANGO_ATTR_BACKGROUND:
|
||||
RGBA_ATTR (background_rgba, bg_alpha);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_UNDERLINE:
|
||||
case PANGO_ATTR_UNDERLINE:
|
||||
INT_ATTR (underline);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_UNDERLINE_COLOR:
|
||||
RGBA_ATTR (underline_rgba);
|
||||
case PANGO_ATTR_UNDERLINE_COLOR:
|
||||
RGBA_ATTR (underline_rgba, fg_alpha);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_OVERLINE:
|
||||
case PANGO_ATTR_OVERLINE:
|
||||
INT_ATTR (overline);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_OVERLINE_COLOR:
|
||||
RGBA_ATTR (overline_rgba);
|
||||
case PANGO_ATTR_OVERLINE_COLOR:
|
||||
RGBA_ATTR (overline_rgba, fg_alpha);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_STRIKETHROUGH:
|
||||
case PANGO_ATTR_STRIKETHROUGH:
|
||||
INT_ATTR (strikethrough);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_STRIKETHROUGH_COLOR:
|
||||
RGBA_ATTR (strikethrough_rgba);
|
||||
case PANGO_ATTR_STRIKETHROUGH_COLOR:
|
||||
RGBA_ATTR (strikethrough_rgba, fg_alpha);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_RISE:
|
||||
case PANGO_ATTR_RISE:
|
||||
INT_ATTR (rise);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_SCALE:
|
||||
case PANGO_ATTR_SCALE:
|
||||
FLOAT_ATTR (scale);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_FALLBACK:
|
||||
case PANGO_ATTR_FALLBACK:
|
||||
INT_ATTR (fallback);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_LETTER_SPACING:
|
||||
case PANGO_ATTR_LETTER_SPACING:
|
||||
INT_ATTR (letter_spacing);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_FONT_FEATURES:
|
||||
case PANGO_ATTR_FONT_FEATURES:
|
||||
STRING_ATTR (font_features);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_ALLOW_BREAKS:
|
||||
case PANGO_ATTR_ALLOW_BREAKS:
|
||||
INT_ATTR (allow_breaks);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_SHOW:
|
||||
case PANGO_ATTR_SHOW:
|
||||
INT_ATTR (show_spaces);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_INSERT_HYPHENS:
|
||||
case PANGO_ATTR_INSERT_HYPHENS:
|
||||
INT_ATTR (insert_hyphens);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_LINE_HEIGHT:
|
||||
case PANGO_ATTR_LINE_HEIGHT:
|
||||
FLOAT_ATTR (line_height);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_ABSOLUTE_LINE_HEIGHT:
|
||||
case PANGO_ATTR_ABSOLUTE_LINE_HEIGHT:
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_LINE_SPACING:
|
||||
INT_ATTR (pixels_inside_wrap);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_WORD:
|
||||
case PANGO_ATTR_WORD:
|
||||
VOID_ATTR (word);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_SENTENCE:
|
||||
case PANGO_ATTR_SENTENCE:
|
||||
VOID_ATTR (sentence);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_PARAGRAPH:
|
||||
VOID_ATTR (paragraph);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_BASELINE_SHIFT:
|
||||
case PANGO_ATTR_BASELINE_SHIFT:
|
||||
INT_ATTR (baseline_shift);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_FONT_SCALE:
|
||||
case PANGO_ATTR_FONT_SCALE:
|
||||
INT_ATTR (font_scale);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_ABSOLUTE_SIZE:
|
||||
case PANGO2_ATTR_GRAVITY:
|
||||
case PANGO2_ATTR_GRAVITY_HINT:
|
||||
case PANGO_ATTR_SHAPE:
|
||||
case PANGO_ATTR_ABSOLUTE_SIZE:
|
||||
case PANGO_ATTR_GRAVITY:
|
||||
case PANGO_ATTR_GRAVITY_HINT:
|
||||
case PANGO_ATTR_FOREGROUND_ALPHA:
|
||||
case PANGO_ATTR_BACKGROUND_ALPHA:
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_TEXT_TRANSFORM:
|
||||
case PANGO_ATTR_TEXT_TRANSFORM:
|
||||
INT_ATTR (text_transform);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_INVALID:
|
||||
case PANGO_ATTR_INVALID:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_slist_free_full (attrs, (GDestroyNotify)pango2_attribute_destroy);
|
||||
g_slist_free_full (attrs, (GDestroyNotify)pango_attribute_destroy);
|
||||
|
||||
#undef LANGUAGE_ATTR
|
||||
#undef STRING_ATTR
|
||||
@@ -311,9 +329,9 @@ typedef struct
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter iter;
|
||||
GtkTextMark *mark;
|
||||
Pango2AttrList *attributes;
|
||||
PangoAttrList *attributes;
|
||||
char *text;
|
||||
Pango2AttrIterator *attr;
|
||||
PangoAttrIterator *attr;
|
||||
} MarkupData;
|
||||
|
||||
static void
|
||||
@@ -322,8 +340,8 @@ free_markup_data (MarkupData *mdata)
|
||||
g_free (mdata->markup);
|
||||
g_clear_pointer (&mdata->parser, g_markup_parse_context_free);
|
||||
gtk_text_buffer_delete_mark (mdata->buffer, mdata->mark);
|
||||
g_clear_pointer (&mdata->attr, pango2_attr_iterator_destroy);
|
||||
g_clear_pointer (&mdata->attributes, pango2_attr_list_unref);
|
||||
g_clear_pointer (&mdata->attr, pango_attr_iterator_destroy);
|
||||
g_clear_pointer (&mdata->attributes, pango_attr_list_unref);
|
||||
g_free (mdata->text);
|
||||
g_object_unref (mdata->buffer);
|
||||
g_free (mdata);
|
||||
@@ -349,7 +367,7 @@ insert_markup_idle (gpointer data)
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
pango2_attr_iterator_range (mdata->attr, &start, &end);
|
||||
pango_attr_iterator_range (mdata->attr, &start, &end);
|
||||
|
||||
if (end == G_MAXINT) /* last chunk */
|
||||
end = start - 1; /* resulting in -1 to be passed to _insert */
|
||||
@@ -362,7 +380,7 @@ insert_markup_idle (gpointer data)
|
||||
|
||||
gtk_text_buffer_get_iter_at_mark (mdata->buffer, &mdata->iter, mdata->mark);
|
||||
}
|
||||
while (pango2_attr_iterator_next (mdata->attr));
|
||||
while (pango_attr_iterator_next (mdata->attr));
|
||||
|
||||
free_markup_data (mdata);
|
||||
return G_SOURCE_REMOVE;
|
||||
@@ -398,7 +416,7 @@ parse_markup_idle (gpointer data)
|
||||
mdata->pos += 4096;
|
||||
} while (mdata->pos < mdata->len);
|
||||
|
||||
if (!pango2_markup_parser_finish (mdata->parser,
|
||||
if (!pango_markup_parser_finish (mdata->parser,
|
||||
&mdata->attributes,
|
||||
&mdata->text,
|
||||
NULL,
|
||||
@@ -417,7 +435,7 @@ parse_markup_idle (gpointer data)
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
mdata->attr = pango2_attr_list_get_iterator (mdata->attributes);
|
||||
mdata->attr = pango_attr_list_get_iterator (mdata->attributes);
|
||||
insert_markup_idle (data);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
@@ -443,7 +461,7 @@ insert_markup (GtkTextBuffer *buffer,
|
||||
data->markup = markup;
|
||||
data->len = len;
|
||||
|
||||
data->parser = pango2_markup_parser_new (0);
|
||||
data->parser = pango_markup_parser_new (0);
|
||||
data->pos = 0;
|
||||
|
||||
/* create mark with right gravity */
|
||||
|
||||
@@ -25,7 +25,7 @@ static GtkWidget *show_extents = NULL;
|
||||
static GtkWidget *show_pixels = NULL;
|
||||
static GtkWidget *show_outlines = NULL;
|
||||
|
||||
static Pango2Context *context;
|
||||
static PangoContext *context;
|
||||
|
||||
static int scale = 7;
|
||||
static double pixel_alpha = 1.0;
|
||||
@@ -35,15 +35,14 @@ static void
|
||||
update_image (void)
|
||||
{
|
||||
const char *text;
|
||||
Pango2FontDescription *desc;
|
||||
Pango2Layout *layout;
|
||||
Pango2Rectangle ink, logical;
|
||||
PangoFontDescription *desc;
|
||||
PangoLayout *layout;
|
||||
PangoRectangle ink, logical;
|
||||
int baseline;
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
GdkPixbuf *pixbuf;
|
||||
GdkPixbuf *pixbuf2;
|
||||
const char *hint;
|
||||
cairo_font_options_t *fopt;
|
||||
cairo_hint_style_t hintstyle;
|
||||
cairo_hint_metrics_t hintmetrics;
|
||||
@@ -56,20 +55,25 @@ update_image (void)
|
||||
text = gtk_editable_get_text (GTK_EDITABLE (entry));
|
||||
desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (font_button));
|
||||
|
||||
fopt = cairo_font_options_copy (pango2_cairo_context_get_font_options (context));
|
||||
fopt = cairo_font_options_copy (pango_cairo_context_get_font_options (context));
|
||||
|
||||
hint = gtk_combo_box_get_active_id (GTK_COMBO_BOX (hinting));
|
||||
hintstyle = CAIRO_HINT_STYLE_DEFAULT;
|
||||
if (hint)
|
||||
switch (gtk_drop_down_get_selected (GTK_DROP_DOWN (hinting)))
|
||||
{
|
||||
if (strcmp (hint, "none") == 0)
|
||||
hintstyle = CAIRO_HINT_STYLE_NONE;
|
||||
else if (strcmp (hint, "slight") == 0)
|
||||
hintstyle = CAIRO_HINT_STYLE_SLIGHT;
|
||||
else if (strcmp (hint, "medium") == 0)
|
||||
hintstyle = CAIRO_HINT_STYLE_MEDIUM;
|
||||
else if (strcmp (hint, "full") == 0)
|
||||
hintstyle = CAIRO_HINT_STYLE_FULL;
|
||||
case 0:
|
||||
hintstyle = CAIRO_HINT_STYLE_NONE;
|
||||
break;
|
||||
case 1:
|
||||
hintstyle = CAIRO_HINT_STYLE_SLIGHT;
|
||||
break;
|
||||
case 2:
|
||||
hintstyle = CAIRO_HINT_STYLE_MEDIUM;
|
||||
break;
|
||||
case 3:
|
||||
hintstyle = CAIRO_HINT_STYLE_FULL;
|
||||
break;
|
||||
default:
|
||||
hintstyle = CAIRO_HINT_STYLE_DEFAULT;
|
||||
break;
|
||||
}
|
||||
cairo_font_options_set_hint_style (fopt, hintstyle);
|
||||
|
||||
@@ -85,20 +89,20 @@ update_image (void)
|
||||
antialias = CAIRO_ANTIALIAS_NONE;
|
||||
cairo_font_options_set_antialias (fopt, antialias);
|
||||
|
||||
pango2_context_set_round_glyph_positions (context, hintmetrics == CAIRO_HINT_METRICS_ON);
|
||||
pango2_cairo_context_set_font_options (context, fopt);
|
||||
pango_context_set_round_glyph_positions (context, hintmetrics == CAIRO_HINT_METRICS_ON);
|
||||
pango_cairo_context_set_font_options (context, fopt);
|
||||
cairo_font_options_destroy (fopt);
|
||||
pango2_context_changed (context);
|
||||
pango_context_changed (context);
|
||||
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (text_radio)))
|
||||
{
|
||||
layout = pango2_layout_new (context);
|
||||
pango2_layout_set_font_description (layout, desc);
|
||||
pango2_layout_set_text (layout, text, -1);
|
||||
pango2_lines_get_extents (pango2_layout_get_lines (layout), &ink, &logical);
|
||||
baseline = pango2_lines_get_baseline (pango2_layout_get_lines (layout));
|
||||
layout = pango_layout_new (context);
|
||||
pango_layout_set_font_description (layout, desc);
|
||||
pango_layout_set_text (layout, text, -1);
|
||||
pango_layout_get_extents (layout, &ink, &logical);
|
||||
baseline = pango_layout_get_baseline (layout);
|
||||
|
||||
pango2_extents_to_pixels (&ink, NULL);
|
||||
pango_extents_to_pixels (&ink, NULL);
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, ink.width + 20, ink.height + 20);
|
||||
cr = cairo_create (surface);
|
||||
@@ -108,9 +112,9 @@ update_image (void)
|
||||
cairo_set_source_rgba (cr, 0, 0, 0, pixel_alpha);
|
||||
|
||||
cairo_move_to (cr, 10, 10);
|
||||
pango2_cairo_show_layout (cr, layout);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
|
||||
pango2_cairo_layout_path (cr, layout);
|
||||
pango_cairo_layout_path (cr, layout);
|
||||
path = cairo_copy_path (cr);
|
||||
|
||||
cairo_destroy (cr);
|
||||
@@ -154,15 +158,15 @@ update_image (void)
|
||||
cairo_set_source_rgb (cr, 0, 0, 1);
|
||||
|
||||
cairo_rectangle (cr,
|
||||
scale * (10 + pango2_units_to_double (logical.x)) - 0.5,
|
||||
scale * (10 + pango2_units_to_double (logical.y)) - 0.5,
|
||||
scale * pango2_units_to_double (logical.width) + 1,
|
||||
scale * pango2_units_to_double (logical.height) + 1);
|
||||
scale * (10 + pango_units_to_double (logical.x)) - 0.5,
|
||||
scale * (10 + pango_units_to_double (logical.y)) - 0.5,
|
||||
scale * pango_units_to_double (logical.width) + 1,
|
||||
scale * pango_units_to_double (logical.height) + 1);
|
||||
cairo_stroke (cr);
|
||||
cairo_move_to (cr, scale * (10 + pango2_units_to_double (logical.x)) - 0.5,
|
||||
scale * (10 + pango2_units_to_double (baseline)) - 0.5);
|
||||
cairo_line_to (cr, scale * (10 + pango2_units_to_double (logical.x + logical.width)) + 1,
|
||||
scale * (10 + pango2_units_to_double (baseline)) - 0.5);
|
||||
cairo_move_to (cr, scale * (10 + pango_units_to_double (logical.x)) - 0.5,
|
||||
scale * (10 + pango_units_to_double (baseline)) - 0.5);
|
||||
cairo_line_to (cr, scale * (10 + pango_units_to_double (logical.x + logical.width)) + 1,
|
||||
scale * (10 + pango_units_to_double (baseline)) - 0.5);
|
||||
cairo_stroke (cr);
|
||||
cairo_set_source_rgb (cr, 1, 0, 0);
|
||||
cairo_rectangle (cr,
|
||||
@@ -206,10 +210,9 @@ update_image (void)
|
||||
}
|
||||
else
|
||||
{
|
||||
Pango2LineIter *iter;
|
||||
Pango2Run *run;
|
||||
Pango2GlyphString *glyphs;
|
||||
Pango2GlyphInfo *g;
|
||||
PangoLayoutIter *iter;
|
||||
PangoLayoutRun *run;
|
||||
PangoGlyphInfo *g;
|
||||
int i, j;
|
||||
GString *str;
|
||||
gunichar ch;
|
||||
@@ -218,53 +221,61 @@ update_image (void)
|
||||
text = " ";
|
||||
|
||||
ch = g_utf8_get_char (text);
|
||||
|
||||
str = g_string_new ("");
|
||||
layout = pango_layout_new (context);
|
||||
|
||||
retry:
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
g_string_append_unichar (str, ch);
|
||||
g_string_append_unichar (str, 0x200c);
|
||||
}
|
||||
|
||||
layout = pango2_layout_new (context);
|
||||
pango2_layout_set_font_description (layout, desc);
|
||||
pango2_layout_set_text (layout, str->str, -1);
|
||||
pango_layout_set_font_description (layout, desc);
|
||||
pango_layout_set_text (layout, str->str, -1);
|
||||
pango_layout_get_extents (layout, &ink, &logical);
|
||||
pango_extents_to_pixels (&logical, NULL);
|
||||
|
||||
iter = pango_layout_get_iter (layout);
|
||||
run = pango_layout_iter_get_run (iter);
|
||||
|
||||
if (run->glyphs->num_glyphs < 8)
|
||||
{
|
||||
/* not a good char to use */
|
||||
g_string_truncate (str, 0);
|
||||
ch = 'a';
|
||||
goto retry;
|
||||
}
|
||||
|
||||
g_string_free (str, TRUE);
|
||||
pango2_lines_get_extents (pango2_layout_get_lines (layout), &ink, &logical);
|
||||
pango2_extents_to_pixels (&logical, NULL);
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, logical.width * 3 / 2, 4*logical.height);
|
||||
cr = cairo_create (surface);
|
||||
cairo_set_source_rgb (cr, 1, 1, 1);
|
||||
cairo_paint (cr);
|
||||
|
||||
iter = pango2_layout_get_iter (layout);
|
||||
run = pango2_line_iter_get_run (iter);
|
||||
glyphs = pango2_run_get_glyphs (run);
|
||||
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
g = &(glyphs->glyphs[2*i]);
|
||||
g->geometry.width = PANGO2_UNITS_ROUND (g->geometry.width * 3 / 2);
|
||||
g = &(run->glyphs->glyphs[2*i]);
|
||||
g->geometry.width = PANGO_UNITS_ROUND (g->geometry.width * 3 / 2);
|
||||
}
|
||||
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
g = &(glyphs->glyphs[2*i]);
|
||||
g->geometry.x_offset = i * (PANGO2_SCALE / 4);
|
||||
g->geometry.y_offset = j * (PANGO2_SCALE / 4);
|
||||
g = &(run->glyphs->glyphs[2*i]);
|
||||
g->geometry.x_offset = i * (PANGO_SCALE / 4);
|
||||
g->geometry.y_offset = j * (PANGO_SCALE / 4);
|
||||
}
|
||||
|
||||
cairo_move_to (cr, 0, j * logical.height);
|
||||
pango2_cairo_show_layout (cr, layout);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
}
|
||||
|
||||
cairo_destroy (cr);
|
||||
pango2_line_iter_free (iter);
|
||||
pango_layout_iter_free (iter);
|
||||
g_object_unref (layout);
|
||||
|
||||
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, cairo_image_surface_get_width (surface), cairo_image_surface_get_height (surface));
|
||||
@@ -277,7 +288,7 @@ update_image (void)
|
||||
|
||||
g_object_unref (pixbuf2);
|
||||
|
||||
pango2_font_description_free (desc);
|
||||
pango_font_description_free (desc);
|
||||
}
|
||||
|
||||
static gboolean fading = FALSE;
|
||||
@@ -411,7 +422,7 @@ do_fontrendering (GtkWidget *do_widget)
|
||||
g_signal_connect (down_button, "clicked", G_CALLBACK (scale_down), NULL);
|
||||
g_signal_connect (entry, "notify::text", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (font_button, "notify::font-desc", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (hinting, "notify::active", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (hinting, "notify::selected", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (anti_alias, "notify::active", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (hint_metrics, "notify::active", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (text_radio, "notify::active", G_CALLBACK (update_image), NULL);
|
||||
|
||||
@@ -116,15 +116,18 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="hinting">
|
||||
<property name="active">0</property>
|
||||
<object class="GtkDropDown" id="hinting">
|
||||
<property name="valign">center</property>
|
||||
<items>
|
||||
<item translatable="yes" id="none">None</item>
|
||||
<item translatable="yes" id="slight">Slight</item>
|
||||
<item translatable="yes" id="medium">Medium</item>
|
||||
<item translatable="yes" id="full">Full</item>
|
||||
</items>
|
||||
<property name="model">
|
||||
<object class="GtkStringList">
|
||||
<items>
|
||||
<item translatable="yes">None</item>
|
||||
<item translatable="yes">Slight</item>
|
||||
<item translatable="yes">Medium</item>
|
||||
<item translatable="yes">Full</item>
|
||||
</items>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
|
||||
@@ -144,7 +144,6 @@ make_shader_stack (const char *name,
|
||||
GtkTextBuffer *buffer;
|
||||
GBytes *bytes;
|
||||
GtkEventController *controller;
|
||||
GtkCssProvider *provider;
|
||||
GdkPaintable *paintable;
|
||||
|
||||
stack = gtk_shader_stack_new ();
|
||||
@@ -235,12 +234,6 @@ make_shader_stack (const char *name,
|
||||
g_signal_connect (buffer, "changed", G_CALLBACK (text_changed), button);
|
||||
g_object_set_data (G_OBJECT (button), "the-stack", stack);
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (apply_text), buffer);
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_data (provider, "button.small { padding: 0; }", -1);
|
||||
gtk_style_context_add_provider (gtk_widget_get_style_context (button),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
g_object_unref (provider);
|
||||
gtk_widget_set_halign (button, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
|
||||
gtk_widget_add_css_class (button, "small");
|
||||
@@ -274,11 +267,21 @@ make_shader_stack (const char *name,
|
||||
return vbox;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_provider (gpointer data)
|
||||
{
|
||||
GtkStyleProvider *provider = GTK_STYLE_PROVIDER (data);
|
||||
|
||||
gtk_style_context_remove_provider_for_display (gdk_display_get_default (), provider);
|
||||
g_object_unref (provider);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_gltransition_window (GtkWidget *do_widget)
|
||||
{
|
||||
GtkWidget *window, *headerbar, *scale, *outer_grid, *grid, *background;
|
||||
GdkPaintable *paintable;
|
||||
GtkCssProvider *provider;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
|
||||
@@ -333,6 +336,14 @@ create_gltransition_window (GtkWidget *do_widget)
|
||||
make_shader_stack ("Kaleidoscope", "/gltransition/kaleidoscope.glsl", 3, scale),
|
||||
1, 1, 1, 1);
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_data (provider, "button.small { padding: 0; }", -1);
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (window), "provider", provider, remove_provider);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
|
||||
@@ -223,6 +223,7 @@ static void
|
||||
destroy_gear (struct gear *g)
|
||||
{
|
||||
g_free (g->strips);
|
||||
g_free (g->vertices);
|
||||
g_free (g);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ insert_link (GtkTextBuffer *buffer,
|
||||
|
||||
tag = gtk_text_buffer_create_tag (buffer, NULL,
|
||||
"foreground", "blue",
|
||||
"underline", PANGO2_LINE_STYLE_SOLID,
|
||||
"underline", PANGO_UNDERLINE_SINGLE,
|
||||
NULL);
|
||||
g_object_set_data (G_OBJECT (tag), "page", GINT_TO_POINTER (page));
|
||||
gtk_text_buffer_insert_with_tags (buffer, iter, text, -1, tag, NULL);
|
||||
@@ -72,8 +72,8 @@ show_page (GtkTextView *text_view,
|
||||
buffer = gtk_text_view_get_buffer (text_view);
|
||||
|
||||
bold = gtk_text_buffer_create_tag (buffer, NULL,
|
||||
"weight", PANGO2_WEIGHT_BOLD,
|
||||
"scale", PANGO2_SCALE_X_LARGE,
|
||||
"weight", PANGO_WEIGHT_BOLD,
|
||||
"scale", PANGO_SCALE_X_LARGE,
|
||||
NULL);
|
||||
mono = gtk_text_buffer_create_tag (buffer, NULL,
|
||||
"family", "monospace",
|
||||
|
||||
BIN
demos/gtk-demo/icons/48x48/status/starred.png
Normal file
BIN
demos/gtk-demo/icons/48x48/status/starred.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
@@ -123,11 +123,11 @@ populate_emoji_text (void)
|
||||
for (int i = 0; i < 500; i++)
|
||||
{
|
||||
if (i % 2)
|
||||
g_string_append (s, "<span underline=\"solid\" underline_color=\"red\">x</span>");
|
||||
g_string_append (s, "<span underline=\"single\" underline_color=\"red\">x</span>");
|
||||
for (int j = 0; j < 30; j++)
|
||||
{
|
||||
g_string_append (s, "💓");
|
||||
g_string_append (s, "<span underline=\"solid\" underline_color=\"red\">x</span>");
|
||||
g_string_append (s, "<span underline=\"single\" underline_color=\"red\">x</span>");
|
||||
}
|
||||
g_string_append (s, "\n");
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <string.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
#define FOLDER_NAME "/iconview/gnome-fs-directory.png"
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <string.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
enum
|
||||
{
|
||||
COL_TEXT,
|
||||
|
||||
@@ -44,7 +44,7 @@ get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param)
|
||||
gint i;
|
||||
const LCTYPE iso639_lctypes[] = { LOCALE_SISO639LANGNAME, LOCALE_SISO639LANGNAME2 };
|
||||
GHashTable *ht_scripts_langs = (GHashTable *) param;
|
||||
Pango2Language *lang;
|
||||
PangoLanguage *lang;
|
||||
|
||||
gint langname_size, locale_abbrev_size;
|
||||
langname_size = GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, 0);
|
||||
@@ -60,7 +60,7 @@ get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param)
|
||||
langname = g_utf16_to_utf8 (langname_w, -1, NULL, NULL, NULL);
|
||||
locale = g_utf16_to_utf8 (locale_w, -1, NULL, NULL, NULL);
|
||||
p = strchr (locale, '-');
|
||||
lang = pango2_language_from_string (locale);
|
||||
lang = pango_language_from_string (locale);
|
||||
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
|
||||
g_hash_table_insert (ht_scripts_langs, lang, langname);
|
||||
|
||||
@@ -77,7 +77,7 @@ get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param)
|
||||
GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, locale_abbrev_size);
|
||||
|
||||
locale_abbrev = g_utf16_to_utf8 (locale_abbrev_w, -1, NULL, NULL, NULL);
|
||||
lang = pango2_language_from_string (locale_abbrev);
|
||||
lang = pango_language_from_string (locale_abbrev);
|
||||
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
|
||||
g_hash_table_insert (ht_scripts_langs, lang, langname);
|
||||
|
||||
@@ -218,22 +218,22 @@ languages_parse_start_tag (GMarkupParseContext *ctx,
|
||||
|
||||
if (ccode != NULL)
|
||||
g_hash_table_insert (language_map,
|
||||
pango2_language_from_string (ccode),
|
||||
pango_language_from_string (ccode),
|
||||
g_strdup (display_name));
|
||||
|
||||
if (ccode_longB != NULL)
|
||||
g_hash_table_insert (language_map,
|
||||
pango2_language_from_string (ccode_longB),
|
||||
pango_language_from_string (ccode_longB),
|
||||
g_strdup (display_name));
|
||||
|
||||
if (ccode_longT != NULL)
|
||||
g_hash_table_insert (language_map,
|
||||
pango2_language_from_string (ccode_longT),
|
||||
pango_language_from_string (ccode_longT),
|
||||
g_strdup (display_name));
|
||||
|
||||
if (ccode_id != NULL)
|
||||
g_hash_table_insert (language_map,
|
||||
pango2_language_from_string (ccode_id),
|
||||
pango_language_from_string (ccode_id),
|
||||
g_strdup (display_name));
|
||||
|
||||
g_free (display_name);
|
||||
@@ -295,7 +295,7 @@ languages_init (void)
|
||||
}
|
||||
|
||||
const char *
|
||||
get_language_name (Pango2Language *language)
|
||||
get_language_name (PangoLanguage *language)
|
||||
{
|
||||
languages_init ();
|
||||
|
||||
@@ -311,5 +311,5 @@ get_language_name_for_tag (guint32 tag)
|
||||
lang = hb_ot_tag_to_language (tag);
|
||||
s = hb_language_to_string (lang);
|
||||
|
||||
return get_language_name (pango2_language_from_string (s));
|
||||
return get_language_name (pango_language_from_string (s));
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#ifndef LANGUAGE_NAMES_H
|
||||
#define LANGUAGE_NAMES_H
|
||||
|
||||
#include <pango2/pango.h>
|
||||
#include <pango/pango.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
const char * get_language_name (Pango2Language *language);
|
||||
const char * get_language_name (PangoLanguage *language);
|
||||
const char * get_language_name_for_tag (guint32 tag);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -72,7 +72,7 @@ do_links (GtkWidget *do_widget)
|
||||
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_max_width_chars (GTK_LABEL (label), 40);
|
||||
gtk_label_set_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_wrap_mode (GTK_LABEL (label), PANGO2_WRAP_WORD);
|
||||
gtk_label_set_wrap_mode (GTK_LABEL (label), PANGO_WRAP_WORD);
|
||||
g_signal_connect (label, "activate-link", G_CALLBACK (activate_link), NULL);
|
||||
gtk_widget_set_margin_start (label, 20);
|
||||
gtk_widget_set_margin_end (label, 20);
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
static GtkTreeModel *model = NULL;
|
||||
static guint timeout = 0;
|
||||
|
||||
@@ -260,12 +260,19 @@ gtk_message_row_state_flags_changed (GtkWidget *widget,
|
||||
GTK_WIDGET_CLASS (gtk_message_row_parent_class)->state_flags_changed (widget, previous_state_flags);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_message_row_dispose (GObject *obj)
|
||||
{
|
||||
gtk_widget_dispose_template (GTK_WIDGET (obj), GTK_TYPE_MESSAGE_ROW);
|
||||
G_OBJECT_CLASS (gtk_message_row_parent_class)->dispose (obj);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_message_row_finalize (GObject *obj)
|
||||
{
|
||||
GtkMessageRowPrivate *priv = GTK_MESSAGE_ROW (obj)->priv;
|
||||
g_object_unref (priv->message);
|
||||
G_OBJECT_CLASS (gtk_message_row_parent_class)->finalize(obj);
|
||||
G_OBJECT_CLASS (gtk_message_row_parent_class)->finalize (obj);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -274,6 +281,7 @@ gtk_message_row_class_init (GtkMessageRowClass *klass)
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gtk_message_row_dispose;
|
||||
object_class->finalize = gtk_message_row_finalize;
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/listbox/listbox.ui");
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user