Compare commits
223 Commits
glyphy-no-
...
path-itera
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
244cdafe1b | ||
|
|
a0d17418de | ||
|
|
093e6241e7 | ||
|
|
67b504f823 | ||
|
|
659bc813a4 | ||
|
|
293c0774b3 | ||
|
|
988062889b | ||
|
|
461922b495 | ||
|
|
7150a53ccb | ||
|
|
1e306b148e | ||
|
|
6af9dc8612 | ||
|
|
35b313f9b0 | ||
|
|
fe84ce8686 | ||
|
|
02a4e5a457 | ||
|
|
a548a91e6d | ||
|
|
fc3c2e0942 | ||
|
|
60e07335a1 | ||
|
|
cb6b968fb5 | ||
|
|
3aa3816125 | ||
|
|
c37c29422a | ||
|
|
db71c07f8f | ||
|
|
bf1b97efd3 | ||
|
|
4d7277f72c | ||
|
|
3296f01edf | ||
|
|
dbcbf0523b | ||
|
|
888abb6f24 | ||
|
|
9b916b329a | ||
|
|
eb3ada6386 | ||
|
|
2a725b658b | ||
|
|
97f605f811 | ||
|
|
4e7d578881 | ||
|
|
438d936f57 | ||
|
|
fc4a464b47 | ||
|
|
785b9541f6 | ||
|
|
a4cbabb80f | ||
|
|
1b5dfcba7e | ||
|
|
ba41edf531 | ||
|
|
bf3892caed | ||
|
|
1e6a95aa1b | ||
|
|
70a9d08e21 | ||
|
|
7511d4e281 | ||
|
|
53ea97decb | ||
|
|
28190ded71 | ||
|
|
8083cb0e47 | ||
|
|
d241ec4f3e | ||
|
|
544320a961 | ||
|
|
ee5a95ba24 | ||
|
|
232260b86b | ||
|
|
857f50649c | ||
|
|
a39d9d60a7 | ||
|
|
5f9bc97291 | ||
|
|
01b3b096fe | ||
|
|
fef69881a7 | ||
|
|
be0eaa64ed | ||
|
|
62087b1ab5 | ||
|
|
6af55a31d7 | ||
|
|
8e57818a52 | ||
|
|
a447c439f4 | ||
|
|
2120ef38d9 | ||
|
|
6077ea4f48 | ||
|
|
c278c78378 | ||
|
|
b64dc75e3a | ||
|
|
447c07bf5e | ||
|
|
2a5f1dc6c7 | ||
|
|
105be5a457 | ||
|
|
0b6b6b0984 | ||
|
|
a0429c8218 | ||
|
|
56649007d0 | ||
|
|
42d0590d80 | ||
|
|
ce4fbcef8e | ||
|
|
7c8171f069 | ||
|
|
33fe93d9f2 | ||
|
|
a8d092f978 | ||
|
|
645043d5a2 | ||
|
|
c6693b7fb7 | ||
|
|
5c4bb1f93b | ||
|
|
d05628c66a | ||
|
|
0e2db8090b | ||
|
|
b4ab398e0d | ||
|
|
26018107d6 | ||
|
|
3e066a0a15 | ||
|
|
23222a97fc | ||
|
|
d4a5872fb0 | ||
|
|
24714cb91c | ||
|
|
b51d8a22ef | ||
|
|
aa0afab960 | ||
|
|
111269019f | ||
|
|
f0d974c6f5 | ||
|
|
d30adc48d4 | ||
|
|
40d3b30770 | ||
|
|
2e7291d0e7 | ||
|
|
48d1dfd195 | ||
|
|
caeccfd2da | ||
|
|
a9082fa5fa | ||
|
|
eb10af0dac | ||
|
|
3387dc8ec3 | ||
|
|
f663617724 | ||
|
|
b42760da4d | ||
|
|
ea72e7e5b3 | ||
|
|
a51003661e | ||
|
|
a483fb2d96 | ||
|
|
f13c8a3cb4 | ||
|
|
51e617daf3 | ||
|
|
f9f96637d7 | ||
|
|
1df5857b07 | ||
|
|
d637398ab0 | ||
|
|
20ead71c0b | ||
|
|
abcfa21c12 | ||
|
|
424c4b4150 | ||
|
|
5d18ea621d | ||
|
|
e00e6f3d5d | ||
|
|
e98ae233fc | ||
|
|
2ad11e12d4 | ||
|
|
3f16f7e0d4 | ||
|
|
166777dd55 | ||
|
|
c8f385e3bc | ||
|
|
89b4f12b38 | ||
|
|
ae509406f1 | ||
|
|
1aa7f18b23 | ||
|
|
cf39c80fe2 | ||
|
|
24fe66a5f3 | ||
|
|
51b786b799 | ||
|
|
9685030632 | ||
|
|
09be7f65d5 | ||
|
|
2f4d931d0d | ||
|
|
61df8d941b | ||
|
|
327c93066d | ||
|
|
7f946eff01 | ||
|
|
03a8b9cf17 | ||
|
|
ba89a22a4d | ||
|
|
657c018242 | ||
|
|
83db8e41a6 | ||
|
|
57e7112781 | ||
|
|
96f92ee207 | ||
|
|
d27e7e0180 | ||
|
|
5c8bd49383 | ||
|
|
e82bdd8c0d | ||
|
|
72f52751c2 | ||
|
|
98269a29b1 | ||
|
|
8bb968bc01 | ||
|
|
c61313cbfe | ||
|
|
96145ae8ed | ||
|
|
1f848bf9fd | ||
|
|
7a8a27bd60 | ||
|
|
3e9c47e6f7 | ||
|
|
69cf0a75c5 | ||
|
|
a8d3aa133c | ||
|
|
e1d4385026 | ||
|
|
7cc29ce236 | ||
|
|
f998505e27 | ||
|
|
64f50b33e4 | ||
|
|
bc20af2741 | ||
|
|
25f61dd5d5 | ||
|
|
0e5f2cd6f6 | ||
|
|
5aef534871 | ||
|
|
f0f7613adb | ||
|
|
72a1bd64e6 | ||
|
|
bd1b3447c4 | ||
|
|
6653f2b4c3 | ||
|
|
b00b0902ca | ||
|
|
59941930f7 | ||
|
|
aa888c0b3f | ||
|
|
c12a09d24e | ||
|
|
79721d64ad | ||
|
|
62e68f72d6 | ||
|
|
0b1bcf8bee | ||
|
|
477fb8fdfb | ||
|
|
1bd820fc60 | ||
|
|
a4247f1358 | ||
|
|
00b5df6b06 | ||
|
|
1e75fc35c8 | ||
|
|
0751f59ee8 | ||
|
|
b5b797b0aa | ||
|
|
ddfe9f15af | ||
|
|
9929726eb2 | ||
|
|
1aa6e721ae | ||
|
|
87d2ce1332 | ||
|
|
6260a33e8e | ||
|
|
2024913cc2 | ||
|
|
0978a794ac | ||
|
|
da51c90d5c | ||
|
|
b1b8a98568 | ||
|
|
4a8122f685 | ||
|
|
7a58439977 | ||
|
|
27fbdcbecb | ||
|
|
5bd13ccf15 | ||
|
|
d30a9e7fa9 | ||
|
|
6e75e26a0c | ||
|
|
6562338502 | ||
|
|
cd5cdad31d | ||
|
|
5da01ec4af | ||
|
|
8da96b9353 | ||
|
|
e042db9348 | ||
|
|
601011ccc0 | ||
|
|
5958abae1d | ||
|
|
a056063395 | ||
|
|
537669e2b0 | ||
|
|
216a368f22 | ||
|
|
fd4da47125 | ||
|
|
411e0c5fbd | ||
|
|
e523d3a50e | ||
|
|
99d6a15049 | ||
|
|
7fb6c04e99 | ||
|
|
08fd9e1f2e | ||
|
|
dd641867a2 | ||
|
|
2cbe89de7d | ||
|
|
4d9e7d30b0 | ||
|
|
65224f4533 | ||
|
|
cd84f5a56e | ||
|
|
4311d17cb1 | ||
|
|
11a0646281 | ||
|
|
492507af11 | ||
|
|
67a3929583 | ||
|
|
413d3819cf | ||
|
|
0f289fddf7 | ||
|
|
92038d6b7f | ||
|
|
6e27579d1f | ||
|
|
390a104ddd | ||
|
|
31727a4ec5 | ||
|
|
add197bcf7 | ||
|
|
e73c4fe133 | ||
|
|
9fbd582951 | ||
|
|
4d673e9c9a |
@@ -26,7 +26,7 @@ variables:
|
||||
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
|
||||
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled -Dbuild-testsuite=true -Dintrospection=enabled"
|
||||
MESON_TEST_TIMEOUT_MULTIPLIER: 3
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v46"
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v48"
|
||||
|
||||
workflow:
|
||||
rules:
|
||||
@@ -418,10 +418,11 @@ reference:
|
||||
--buildtype=release
|
||||
--force-fallback-for=gdk-pixbuf,pango
|
||||
-Dintrospection=enabled
|
||||
-Ddocumentation=true
|
||||
-Dgtk_doc=true
|
||||
-Dgdk-pixbuf:gtk_doc=true
|
||||
-Dpango:gtk_doc=true
|
||||
-Ddemos=false
|
||||
-Dbuild-demos=false
|
||||
-Dbuild-examples=false
|
||||
-Dbuild-tests=false
|
||||
-Dbuild-testsuite=false
|
||||
|
||||
@@ -32,6 +32,7 @@ RUN dnf -y install \
|
||||
glib2-static \
|
||||
glibc-devel \
|
||||
glibc-headers \
|
||||
glslc \
|
||||
gnupg2 \
|
||||
gobject-introspection-devel \
|
||||
graphene-devel \
|
||||
|
||||
32
.gitlab-ci/run-single-test.sh
Executable file
32
.gitlab-ci/run-single-test.sh
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/sh
|
||||
#
|
||||
builddir=$1
|
||||
suite=$2
|
||||
unit=$3
|
||||
|
||||
echo "** builddir: ${builddir}"
|
||||
echo "** suite: ${suite}"
|
||||
echo "** unit: ${unit}"
|
||||
|
||||
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
|
||||
|
||||
weston --backend=headless-backend.so --socket=wayland-5 --idle-time=0 &
|
||||
compositor=$!
|
||||
|
||||
export WAYLAND_DISPLAY=wayland-5
|
||||
|
||||
meson test -C ${builddir} \
|
||||
--print-errorlogs \
|
||||
--setup=wayland \
|
||||
--suite=${suite} \
|
||||
--no-suite=failing \
|
||||
--no-suite=flaky \
|
||||
--no-suite=wayland_failing \
|
||||
--no-suite=gsk-compare-broadway \
|
||||
--verbose \
|
||||
"${unit}"
|
||||
|
||||
exit_code=$?
|
||||
kill ${compositor}
|
||||
|
||||
exit ${exit_code}
|
||||
@@ -32,7 +32,8 @@ pacman --noconfirm -S --needed \
|
||||
mingw-w64-$MSYS2_ARCH-fribidi \
|
||||
mingw-w64-$MSYS2_ARCH-gst-plugins-bad-libs \
|
||||
mingw-w64-$MSYS2_ARCH-shared-mime-info \
|
||||
mingw-w64-$MSYS2_ARCH-python-gobject
|
||||
mingw-w64-$MSYS2_ARCH-python-gobject \
|
||||
mingw-w64-$MSYS2_ARCH-shaderc
|
||||
|
||||
mkdir -p _ccache
|
||||
export CCACHE_BASEDIR="$(pwd)"
|
||||
|
||||
45
AUTHORS
45
AUTHORS
@@ -7,7 +7,7 @@ Peter Mattis <petm@xcf.berkeley.edu>
|
||||
Spencer Kimball <spencer@xcf.berkeley.edu>
|
||||
Josh MacDonald <jmacd@xcf.berkeley.edu>
|
||||
|
||||
The Team that build GTK 2 (in alphabetical order)
|
||||
The team that build GTK 2 (in alphabetical order)
|
||||
-------------------------------------------------
|
||||
Shawn T. Amundson <amundson@gtk.org>
|
||||
Jerome Bolliet <bolliet@gtk.org>
|
||||
@@ -28,9 +28,8 @@ Jay Painter <jpaint@gtk.org>
|
||||
Manish Singh <manish@gtk.org>
|
||||
Owen Taylor <otaylor@gtk.org>
|
||||
|
||||
The current team (GTK 3 and 4)
|
||||
------------------------------
|
||||
|
||||
The team that built GTK 3
|
||||
-------------------------
|
||||
Jonas Ådahl <jadahl@gmail.com>
|
||||
Tim Bäder <mail@baedert.org>
|
||||
Emmanuele Bassi <ebassi@gnome.org>
|
||||
@@ -40,6 +39,16 @@ Carlos Garnacho <mrgarnacho@gmail.com>
|
||||
Alexander Larsson <alexl@redhat.com>
|
||||
Benjamin Otte <otte@gnome.org>
|
||||
|
||||
The current team (GTK 4)
|
||||
------------------------
|
||||
Jonas Ådahl <jadahl@gmail.com>
|
||||
Emmanuele Bassi <ebassi@gnome.org>
|
||||
Christian Hergert <chergert@gnome.org>
|
||||
Chun-wei Fan <fanchunwei@src.gnome.org>
|
||||
Matthias Clasen <mclasen@redhat.com>
|
||||
Carlos Garnacho <mrgarnacho@gmail.com>
|
||||
Benjamin Otte <otte@gnome.org>
|
||||
|
||||
|
||||
There are many others who have contributed patches; we thank them,
|
||||
GTK is much better because of them.
|
||||
@@ -49,35 +58,15 @@ Over time, GTK has incorporated some pieces of software which
|
||||
started as independent projects. We list the original authors here:
|
||||
|
||||
|
||||
MS-Windows theme engine
|
||||
-----------------------
|
||||
Raymond Penners
|
||||
Dom Lachowicz
|
||||
|
||||
|
||||
Pixbuf theme engine
|
||||
-------------------
|
||||
Owen Taylor
|
||||
|
||||
|
||||
IME input method
|
||||
----------------
|
||||
Takuro Ashie
|
||||
Kazuki IWAMOTO
|
||||
|
||||
|
||||
Mac OS X backend
|
||||
----------------
|
||||
MacOS backend
|
||||
-------------
|
||||
Anders Carlsson
|
||||
|
||||
|
||||
DirectFB backend
|
||||
----------------
|
||||
Denis Oliver Kropp
|
||||
Sven Neumann
|
||||
Mike Emmel
|
||||
|
||||
|
||||
gtkparasite
|
||||
-----------
|
||||
GtkInspector (originally gtkparasite)
|
||||
-------------------------------------
|
||||
Christian Hammond
|
||||
|
||||
150
LOG
Normal file
150
LOG
Normal file
@@ -0,0 +1,150 @@
|
||||
TAP version 13
|
||||
# random seed: R02S22611f6aefc1121b0ab2dc5286960449
|
||||
# GLib-GIO-DEBUG: _g_io_module_get_default: Found default implementation dconf (DConfSettingsBackend) for ‘gsettings-backend’
|
||||
# GLib-GIO-DEBUG: Using cross-namespace EXTERNAL authentication (this will deadlock if server is GDBus < 2.73.3)
|
||||
# GLib-GIO-DEBUG: Using cross-namespace EXTERNAL authentication (this will deadlock if server is GDBus < 2.73.3)
|
||||
1..1
|
||||
# Start of ops tests
|
||||
# testcase 0 op 0
|
||||
collecting#
|
||||
Cubic 0: # M 100.000000 100.000000 C 150.000000 100.000000 200.000000 100.000000 250.000000 100.000000
|
||||
Cubic 1: # M 250.000000 100.000000 C 300.000000 100.000000 350.000000 100.000000 400.000000 100.000000
|
||||
Line 2: # M 400 100 L 200 300
|
||||
Line 3: # M 200 300 L 100 100
|
||||
Cubic 4: # M 200.000000 100.000000 C 250.000000 100.000000 300.000000 100.000000 350.000000 100.000000
|
||||
Cubic 5: # M 350.000000 100.000000 C 400.000000 100.000000 450.000000 100.000000 500.000000 100.000000
|
||||
Line 6: # M 500 100 L 300 300
|
||||
Line 7: # M 300 300 L 200 100
|
||||
splitting#
|
||||
1 intersections between Cubic 0 and Cubic 1#
|
||||
1 intersections between Cubic 0 and Line 3#
|
||||
9 intersections between Cubic 0 and Cubic 4#
|
||||
# split Cubic 0.0 from Cubic 0 at 0.666666: M 100.000000 100.000000 C 133.333298 100.000000 166.666595 100.000000 199.999893 100.000000
|
||||
split Cubic 0.1 from Cubic 0 at 0.666666: M 199.999893 100.000000 C 216.666595 100.000000 233.333298 100.000000 250.000000 100.000000split Cubic 0.4 from Cubic 0 at 0.00600814: M 200.300323 100.000000 C 216.866882 100.000000 233.433441 100.000000 250.000000 100.000000split Cubic 0.7 from Cubic 0 at 0.00604445: M 200.600708 100.000000 C 217.067139 100.000000 233.533569 100.000000 250.000000 100.000000# split Cubic 4.9 from Cubic 4 at 0.00533867: M 200.800812 100.000000 C 250.533875 100.000000 300.266937 100.000000 350.000000 100.000000
|
||||
1 intersections between Cubic 0.1 and Line 7#
|
||||
1 intersections between Cubic 1 and Line 2#
|
||||
9 intersections between Cubic 1 and Cubic 4.9#
|
||||
split Cubic 1.9 from Cubic 1 at 0.00534248: M 250.801361 100.000000 C 300.534241 100.000000 350.267120 100.000000 400.000000 100.000000# split Cubic 4.9.0 from Cubic 4.9 at 0.329756: M 200.800812 100.000000 C 217.200577 100.000000 233.600342 100.000000 250.000122 100.000000
|
||||
# split Cubic 4.9.1 from Cubic 4.9 at 0.329756: M 250.000122 100.000000 C 283.333435 100.000000 316.666718 100.000000 350.000000 100.000000
|
||||
# split Cubic 4.9.6 from Cubic 4.9 at 0.00500283: M 250.500412 100.000000 C 283.666931 100.000000 316.833466 100.000000 350.000000 100.000000
|
||||
9 intersections between Cubic 1.9 and Cubic 5#
|
||||
# split Cubic 1.9.0 from Cubic 1.9 at 0.664877: M 250.801361 100.000000 C 283.867615 100.000000 316.933868 100.000000 350.000122 100.000000
|
||||
split Cubic 1.9.1 from Cubic 1.9 at 0.664877: M 350.000122 100.000000 C 366.666748 100.000000 383.333374 100.000000 400.000000 100.000000split Cubic 1.9.4 from Cubic 1.9 at 0.00601021: M 350.300598 100.000000 C 366.867065 100.000000 383.433533 100.000000 400.000000 100.000000split Cubic 1.9.7 from Cubic 1.9 at 0.00604655: M 350.601074 100.000000 C 367.067383 100.000000 383.533691 100.000000 400.000000 100.000000# split Cubic 5.9 from Cubic 5 at 0.00534248: M 350.801361 100.000000 C 400.534241 100.000000 450.267120 100.000000 500.000000 100.000000
|
||||
1 intersections between Line 2 and Line 3#
|
||||
1 intersections between Line 2 and Line 7#
|
||||
# split Line 2.0 from Line 2 at 0.666667: M 400 100 L 266.667 233.333
|
||||
split Line 2.1 from Line 2 at 0.666667: M 266.667 233.333 L 200 300# split Line 7.0 from Line 7 at 0.333333: M 300 300 L 266.667 233.333
|
||||
# split Line 7.1 from Line 7 at 0.333333: M 266.667 233.333 L 200 100
|
||||
1 intersections between Cubic 4 and Cubic 4.9.0#
|
||||
1 intersections between Cubic 4 and Line 7.1#
|
||||
1 intersections between Cubic 4.9.0 and Cubic 4.9.1#
|
||||
1 intersections between Cubic 4.9.1 and Cubic 4.9.6#
|
||||
1 intersections between Cubic 4.9.6 and Cubic 5#
|
||||
1 intersections between Cubic 5 and Cubic 5.9#
|
||||
1 intersections between Cubic 5.9 and Line 6#
|
||||
1 intersections between Line 6 and Line 7.0#
|
||||
Cubic 0.0: # M 100.000000 100.000000 C 133.333298 100.000000 166.666595 100.000000 199.999893 100.000000
|
||||
Cubic 0.1: # M 199.999893 100.000000 C 200.100037 100.000000 200.200180 100.000000 200.300323 100.000000
|
||||
Cubic 0.4: # M 200.300323 100.000000 C 200.400452 100.000000 200.500580 100.000000 200.600708 100.000000
|
||||
Cubic 0.7: # M 200.600708 100.000000 C 217.067139 100.000000 233.533569 100.000000 250.000000 100.000000
|
||||
Cubic 1: # M 250.000000 100.000000 C 250.267120 100.000000 250.534241 100.000000 250.801361 100.000000
|
||||
Cubic 1.9.0: # M 250.801361 100.000000 C 283.867615 100.000000 316.933868 100.000000 350.000122 100.000000
|
||||
Cubic 1.9.1: # M 350.000122 100.000000 C 350.100281 100.000000 350.200439 100.000000 350.300598 100.000000
|
||||
Cubic 1.9.4: # M 350.300598 100.000000 C 350.400757 100.000000 350.500916 100.000000 350.601074 100.000000
|
||||
Cubic 1.9.7: # M 350.601074 100.000000 C 367.067383 100.000000 383.533691 100.000000 400.000000 100.000000
|
||||
Line 2.0: # M 400 100 L 266.667 233.333
|
||||
Line 2.1: # M 266.667 233.333 L 200 300
|
||||
Line 3: # M 200 300 L 100 100
|
||||
Cubic 4: # M 200.000000 100.000000 C 200.266937 100.000000 200.533875 100.000000 200.800812 100.000000
|
||||
Cubic 4.9.0: # M 200.800812 100.000000 C 217.200577 100.000000 233.600342 100.000000 250.000122 100.000000
|
||||
Cubic 4.9.1: # M 250.000122 100.000000 C 250.166885 100.000000 250.333649 100.000000 250.500412 100.000000
|
||||
Cubic 4.9.6: # M 250.500412 100.000000 C 283.666931 100.000000 316.833466 100.000000 350.000000 100.000000
|
||||
Cubic 5: # M 350.000000 100.000000 C 350.267120 100.000000 350.534241 100.000000 350.801361 100.000000
|
||||
Cubic 5.9: # M 350.801361 100.000000 C 400.534241 100.000000 450.267120 100.000000 500.000000 100.000000
|
||||
Line 6: # M 500 100 L 300 300
|
||||
Line 7.0: # M 300 300 L 266.667 233.333
|
||||
Line 7.1: # M 266.667 233.333 L 200 100
|
||||
classifying#
|
||||
01 Cubic 0.0: # M 100.000000 100.000000 C 133.333298 100.000000 166.666595 100.000000 199.999893 100.000000
|
||||
[11 Cubic 0.7: # M 200.600708 100.000000 C 217.067139 100.000000 233.533569 100.000000 250.000000 100.000000 ]
|
||||
[11 Cubic 1.9.0: # M 250.801361 100.000000 C 283.867615 100.000000 316.933868 100.000000 350.000122 100.000000 ]
|
||||
[11 Cubic 1.9.7: # M 350.601074 100.000000 C 367.067383 100.000000 383.533691 100.000000 400.000000 100.000000 ]
|
||||
[11 Line 2.0: # M 400 100 L 266.667 233.333 ]
|
||||
01 Line 2.1: # M 266.667 233.333 L 200 300
|
||||
01 Line 3: # M 200 300 L 100 100
|
||||
[11 Cubic 4: # M 200.000000 100.000000 C 200.266937 100.000000 200.533875 100.000000 200.800812 100.000000 ]
|
||||
[11 Cubic 4.9.0: # M 200.800812 100.000000 C 217.200577 100.000000 233.600342 100.000000 250.000122 100.000000 ]
|
||||
[11 Cubic 4.9.6: # M 250.500412 100.000000 C 283.666931 100.000000 316.833466 100.000000 350.000000 100.000000 ]
|
||||
[11 Cubic 5: # M 350.000000 100.000000 C 350.267120 100.000000 350.534241 100.000000 350.801361 100.000000 ]
|
||||
01 Cubic 5.9: # M 350.801361 100.000000 C 400.534241 100.000000 450.267120 100.000000 500.000000 100.000000
|
||||
01 Line 6: # M 500 100 L 300 300
|
||||
01 Line 7.0: # M 300 300 L 266.667 233.333
|
||||
[11 Line 7.1: # M 266.667 233.333 L 200 100 ]
|
||||
fixups#
|
||||
# found 3 bad nodes
|
||||
# split Cubic 0/Cubic 4 BAD 200.600723 100.000000
|
||||
# [11 Line 7.1 ] 116.565
|
||||
# [11 Cubic 0.7 ] 180
|
||||
# [11 Cubic 4 ] 180
|
||||
# [11 Cubic 4 ] 180
|
||||
# [11 Cubic 4.9.0 ] 180
|
||||
# >01 Cubic 0.0 360
|
||||
# split Cubic 1/Cubic 4.9 BAD 250.801376 100.000000
|
||||
# [11 Cubic 1.9.0 ] 180
|
||||
# [11 Cubic 4.9.6 ] 180
|
||||
# [11 Cubic 0.7 ] 360
|
||||
# [11 Cubic 4.9.0 ] 360
|
||||
# split Cubic 1.9/Cubic 5 BAD 350.601105 100.000000
|
||||
# [11 Cubic 1.9.7 ] 180
|
||||
# [11 Cubic 5 ] 180
|
||||
# [11 Cubic 5 ] 180
|
||||
# <01 Cubic 5.9 180
|
||||
# [11 Cubic 1.9.0 ] 360
|
||||
# [11 Cubic 4.9.6 ] 360
|
||||
reassembling#
|
||||
start new contour Cubic 0.0#
|
||||
# Cubic 0.0 ends at:
|
||||
# start 0 100.000000 100.000000
|
||||
# >01 Line 3 116.565
|
||||
# (10 Cubic 0.0 ) 180
|
||||
picking cw#
|
||||
append Line 3#
|
||||
# Line 3 ends at:
|
||||
# end 2 200.000000 300.000000
|
||||
# >01 Line 2.1 225
|
||||
# (10 Line 3 ) 296.565
|
||||
picking cw#
|
||||
append Line 2.1#
|
||||
# Line 2.1 ends at:
|
||||
# split Line 2/Line 7 266.666656 233.333344
|
||||
# (10 Line 2.1 ) 45
|
||||
# >01 Line 7.0 116.565
|
||||
# [11 Line 2.0 ] 225
|
||||
# [11 Line 7.1 ] 296.565
|
||||
picking cw#
|
||||
append Line 7.0#
|
||||
# Line 7.0 ends at:
|
||||
# end 6 300.000000 300.000000
|
||||
# >01 Line 6 225
|
||||
# (10 Line 7.0 ) 296.565
|
||||
picking cw#
|
||||
append Line 6#
|
||||
# Line 6 ends at:
|
||||
# end 5 500.000000 100.000000
|
||||
# (10 Line 6 ) 45
|
||||
# >01 Cubic 5.9 360
|
||||
picking cw#
|
||||
append Cubic 5.9#
|
||||
# Cubic 5.9 ends at:
|
||||
# split Cubic 1.9/Cubic 5 BAD 350.601105 100.000000
|
||||
# [11 Cubic 1.9.7 ] 180
|
||||
# [11 Cubic 5 ] 180
|
||||
# [11 Cubic 5 ] 180
|
||||
# (10 Cubic 5.9 ) 180
|
||||
# [11 Cubic 1.9.0 ] 360
|
||||
# [11 Cubic 4.9.6 ] 360
|
||||
picking cw#
|
||||
**
|
||||
ERROR:../testsuite/gsk/path-ops.c:359:test_ops_simple: assertion failed (s == tests[i].out): ("M 354.60110473632812 100 A 4 4 0 0 0 346.60110473632812 100 A 4 4 0 0 0 354.60110473632812 100 z M 252.80137634277344 100 A 2 2 0 0 0 248.80137634277344 100 A 2 2 0 0 0 252.80137634277344 100 z M 204.60072326660156 100 A 4 4 0 0 0 196.60072326660156 100 A 4 4 0 0 0 204.60072326660156 100 z" == "M 100 100 z")
|
||||
not ok /ops/simple - ERROR:../testsuite/gsk/path-ops.c:359:test_ops_simple: assertion failed (s == tests[i].out): ("M 354.60110473632812 100 A 4 4 0 0 0 346.60110473632812 100 A 4 4 0 0 0 354.60110473632812 100 z M 252.80137634277344 100 A 2 2 0 0 0 248.80137634277344 100 A 2 2 0 0 0 252.80137634277344 100 z M 204.60072326660156 100 A 4 4 0 0 0 196.60072326660156 100 A 4 4 0 0 0 204.60072326660156 100 z" == "M 100 100 z")
|
||||
Bail out!
|
||||
134
NEWS
134
NEWS
@@ -1,6 +1,138 @@
|
||||
Overview of Changes in 4.11.5, xx-xx-xxxx
|
||||
Overview of Changes in 4.13.0, xx-xx-xxxx
|
||||
=========================================
|
||||
|
||||
Overview of Changes in 4.12.0, 05-08-2023
|
||||
=========================================
|
||||
|
||||
* List widgets:
|
||||
- Add scroll_to APIs
|
||||
|
||||
* GtkFileLauncher:
|
||||
- Add an always-ask property
|
||||
|
||||
* GtkTextView:
|
||||
- Make backspace behavior match GtkEntry
|
||||
|
||||
* gsk:
|
||||
- Fix handling of luminance in mask nodes
|
||||
|
||||
* Text rendering:
|
||||
- Automate the setting of gtk-hint-font-metrics from the
|
||||
scale factor. This improves font rendering in flatpaks
|
||||
|
||||
* Wayland:
|
||||
- Fix behavior of stylus buttons
|
||||
- Support suspended window state
|
||||
|
||||
* Vulkan:
|
||||
- Many improvements
|
||||
|
||||
* Tools:
|
||||
- Add gtk4-rendernode-tool
|
||||
|
||||
* Debugging:
|
||||
- Drop the GTK_DEBUG_TOUCHSCREEN flag
|
||||
|
||||
* Build:
|
||||
- Some build options have been renamed:
|
||||
gtk_doc -> documentation
|
||||
update_screenshots -> screenshots
|
||||
The old names still work
|
||||
|
||||
* Translation updates:
|
||||
Georgian
|
||||
Greek
|
||||
Hebrew
|
||||
Persian
|
||||
Vietnamese
|
||||
|
||||
* Contributors:
|
||||
Aleksandr Melman
|
||||
Alexander Mikhaylenko
|
||||
Alexander Shopov
|
||||
Alexandre Franke
|
||||
Alice Mikhaylenko
|
||||
António Fernandes
|
||||
Arjan Molenaar
|
||||
Asier Sarasua Garmendia
|
||||
Balázs Meskó
|
||||
Balázs Úr
|
||||
Barnabás Pőcze
|
||||
Bart Jacobs
|
||||
Benjamin Otte
|
||||
Bilal Elmoussaoui
|
||||
Boyuan Yang
|
||||
Bruce Cowan
|
||||
Calvin Walton
|
||||
Cam Cook
|
||||
Chris Mayo
|
||||
Christian Hergert
|
||||
Christopher Davis
|
||||
Chun-wei Fan
|
||||
Corey Berla
|
||||
Danial Behzadi
|
||||
Daniel Boles
|
||||
Daniel Rusek
|
||||
Efstathios Iosifidis
|
||||
Ekaterine Papava
|
||||
Emin Tufan Çetin
|
||||
Emmanuele Bassi
|
||||
Erik Schilling
|
||||
Fabio Tomat
|
||||
FeRD (Frank Dana)
|
||||
Fina Wilke
|
||||
FineFindus
|
||||
Fran Dieguez
|
||||
G.Willems
|
||||
Georges Basile Stavracas Neto
|
||||
Guillaume Bernard
|
||||
Hugo Carvalho
|
||||
Ivan Molodetskikh
|
||||
Jason Francis
|
||||
Jonas Ådahl
|
||||
Jordan Petridis
|
||||
Jordi Mas
|
||||
José Expósito
|
||||
José Roberto de Souza
|
||||
Khalid Abu Shawarib
|
||||
Kévin Commaille
|
||||
Leônidas Araújo
|
||||
Luca Bacci
|
||||
Ludovico de Nittis
|
||||
Lukáš Tyrychtr
|
||||
Marc-André Lureau
|
||||
Marco Trevisan (Treviño)
|
||||
Matt Turner
|
||||
Matthias Clasen
|
||||
Maximiliano Sandoval R
|
||||
Michael Catanzaro
|
||||
Michel Dänzer
|
||||
Mohammed Sadiq
|
||||
Nathan Follens
|
||||
Nelson Benítez León
|
||||
Ngọc Quân Trần
|
||||
Niels De Graef
|
||||
Olivier Crête
|
||||
Patrick Griffis
|
||||
Piotr Drąg
|
||||
Sabri Ünal
|
||||
Sebastian Keller
|
||||
Sophie Herold
|
||||
Sébastien Le Roux
|
||||
Takao Fujiwara
|
||||
Thomas Lange
|
||||
Yiğit Burak
|
||||
Yosef Or Boczko
|
||||
Yuri Chornoivan
|
||||
Zander Brown
|
||||
al_SeveR
|
||||
dgsasha
|
||||
sumibi-yakitori
|
||||
tszymanski
|
||||
velsinki
|
||||
Алексей Шилин
|
||||
Арсений Засыпкин
|
||||
|
||||
Overview of Changes in 4.11.4, 03-07-2023
|
||||
=========================================
|
||||
|
||||
|
||||
23
README.md
23
README.md
@@ -67,6 +67,13 @@ building for:
|
||||
- [Graphene](https://github.com/ebassi/graphene)
|
||||
- [Xkb-common](https://github.com/xkbcommon/libxkbcommon)
|
||||
|
||||
If you are building the Wayland backend, you will also need:
|
||||
|
||||
- Wayland-client
|
||||
- Wayland-protocols
|
||||
- Wayland-cursor
|
||||
- Wayland-EGL
|
||||
|
||||
If you are building the X11 backend, you will also need:
|
||||
|
||||
- Xlib, and the following X extensions:
|
||||
@@ -79,32 +86,24 @@ If you are building the X11 backend, you will also need:
|
||||
- xdamage
|
||||
- xcomposite
|
||||
|
||||
If you are building the Wayland backend, you will also need:
|
||||
|
||||
- Wayland-client
|
||||
- Wayland-protocols
|
||||
- Wayland-cursor
|
||||
- Wayland-EGL
|
||||
|
||||
Once you have all the necessary dependencies, you can build GTK by using
|
||||
Meson:
|
||||
|
||||
```sh
|
||||
$ meson _build .
|
||||
$ cd _build
|
||||
$ ninja
|
||||
$ meson setup _build
|
||||
$ meson compile -C_build
|
||||
```
|
||||
|
||||
You can run the test suite using:
|
||||
|
||||
```sh
|
||||
$ meson test
|
||||
$ meson test -C_build
|
||||
```
|
||||
|
||||
And, finally, you can install GTK using:
|
||||
|
||||
```
|
||||
$ sudo ninja install
|
||||
$ sudo meson install -C_build
|
||||
```
|
||||
|
||||
Complete information about installing GTK and related libraries
|
||||
|
||||
@@ -483,6 +483,8 @@ constraint_editor_window_class_init (ConstraintEditorWindowClass *class)
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
g_type_ensure (CONSTRAINT_VIEW_TYPE);
|
||||
|
||||
object_class->dispose = constraint_editor_window_dispose;
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class,
|
||||
|
||||
@@ -20,8 +20,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "constraint-editor.h"
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
#include "constraint-view.h"
|
||||
|
||||
struct _ConstraintEditor
|
||||
{
|
||||
@@ -66,7 +65,7 @@ static const char *
|
||||
get_target_name (GtkConstraintTarget *target)
|
||||
{
|
||||
if (target == NULL)
|
||||
return "super";
|
||||
return "Super";
|
||||
else if (GTK_IS_WIDGET (target))
|
||||
return gtk_widget_get_name (GTK_WIDGET (target));
|
||||
else if (GTK_IS_CONSTRAINT_GUIDE (target))
|
||||
@@ -80,62 +79,29 @@ constraint_target_combo (GListModel *model,
|
||||
GtkWidget *combo,
|
||||
gboolean is_source)
|
||||
{
|
||||
GtkStringList *targets;
|
||||
int i;
|
||||
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "super", "Super");
|
||||
targets = gtk_string_list_new (NULL);
|
||||
|
||||
gtk_string_list_append (targets, "Super");
|
||||
|
||||
if (model)
|
||||
{
|
||||
for (i = 0; i < g_list_model_get_n_items (model); i++)
|
||||
{
|
||||
GObject *item = g_list_model_get_object (model, i);
|
||||
const char *name;
|
||||
|
||||
if (GTK_IS_CONSTRAINT (item))
|
||||
continue;
|
||||
|
||||
name = get_target_name (GTK_CONSTRAINT_TARGET (item));
|
||||
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), name, name);
|
||||
gtk_string_list_append (targets, get_target_name (GTK_CONSTRAINT_TARGET (item)));
|
||||
g_object_unref (item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_attribute_combo (GtkWidget *combo,
|
||||
gboolean is_source)
|
||||
{
|
||||
if (is_source)
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "none", "None");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "left", "Left");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "right", "Right");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "top", "Top");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "bottom", "Bottom");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "start", "Start");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "end", "End");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "width", "Width");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "height", "Height");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "center-x", "Center X");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "center-y", "Center Y");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "baseline", "Baseline");
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_relation_combo (GtkWidget *combo)
|
||||
{
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "le", "≤");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "eq", "=");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "ge", "≥");
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_strength_combo (GtkWidget *combo)
|
||||
{
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "weak", "Weak");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "medium", "Medium");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "strong", "Strong");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "required", "Required");
|
||||
gtk_drop_down_set_model (GTK_DROP_DOWN (combo), G_LIST_MODEL (targets));
|
||||
g_object_unref (targets);
|
||||
}
|
||||
|
||||
static gpointer
|
||||
@@ -147,7 +113,7 @@ get_target (GListModel *model,
|
||||
if (id == NULL)
|
||||
return NULL;
|
||||
|
||||
if (strcmp ("super", id) == 0)
|
||||
if (strcmp ("Super", id) == 0)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < g_list_model_get_n_items (model); i++)
|
||||
@@ -171,16 +137,65 @@ get_target (GListModel *model,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GtkConstraintAttribute
|
||||
get_target_attr (const char *id)
|
||||
static void
|
||||
select_target (GtkDropDown *combo,
|
||||
const char *target_name)
|
||||
{
|
||||
GtkConstraintAttribute attr;
|
||||
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_ATTRIBUTE);
|
||||
GEnumValue *value = g_enum_get_value_by_nick (class, id);
|
||||
attr = value->value;
|
||||
g_type_class_unref (class);
|
||||
GListModel *model = gtk_drop_down_get_model (combo);
|
||||
|
||||
return attr;
|
||||
for (unsigned int i = 0; i < g_list_model_get_n_items (model); i++)
|
||||
{
|
||||
GtkStringObject *s = g_list_model_get_item (model, i);
|
||||
|
||||
g_object_unref (s);
|
||||
if (strcmp (target_name, gtk_string_object_get_string (s)) == 0)
|
||||
{
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (combo), i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static GtkConstraintAttribute
|
||||
get_attr (unsigned int id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case 0: return GTK_CONSTRAINT_ATTRIBUTE_NONE;
|
||||
case 1: return GTK_CONSTRAINT_ATTRIBUTE_LEFT;
|
||||
case 2: return GTK_CONSTRAINT_ATTRIBUTE_RIGHT;
|
||||
case 3: return GTK_CONSTRAINT_ATTRIBUTE_TOP;
|
||||
case 4: return GTK_CONSTRAINT_ATTRIBUTE_BOTTOM;
|
||||
case 5: return GTK_CONSTRAINT_ATTRIBUTE_START;
|
||||
case 6: return GTK_CONSTRAINT_ATTRIBUTE_END;
|
||||
case 7: return GTK_CONSTRAINT_ATTRIBUTE_WIDTH;
|
||||
case 8: return GTK_CONSTRAINT_ATTRIBUTE_HEIGHT;
|
||||
case 9: return GTK_CONSTRAINT_ATTRIBUTE_CENTER_X;
|
||||
case 10: return GTK_CONSTRAINT_ATTRIBUTE_CENTER_Y;
|
||||
case 11: return GTK_CONSTRAINT_ATTRIBUTE_BASELINE;
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
get_attr_id (GtkConstraintAttribute attr)
|
||||
{
|
||||
switch (attr)
|
||||
{
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_NONE: return 0;
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_LEFT: return 1;
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_RIGHT: return 2;
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_TOP: return 3;
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_BOTTOM: return 4;
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_START: return 5;
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_END: return 6;
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_WIDTH: return 7;
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_HEIGHT: return 8;
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_CENTER_X: return 9;
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_CENTER_Y: return 10;
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_BASELINE: return 11;
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
@@ -195,15 +210,27 @@ get_attr_nick (GtkConstraintAttribute attr)
|
||||
}
|
||||
|
||||
static GtkConstraintRelation
|
||||
get_relation (const char *id)
|
||||
get_relation (unsigned int id)
|
||||
{
|
||||
GtkConstraintRelation relation;
|
||||
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_RELATION);
|
||||
GEnumValue *value = g_enum_get_value_by_nick (class, id);
|
||||
relation = value->value;
|
||||
g_type_class_unref (class);
|
||||
switch (id)
|
||||
{
|
||||
case 0: return GTK_CONSTRAINT_RELATION_LE;
|
||||
case 1: return GTK_CONSTRAINT_RELATION_EQ;
|
||||
case 2: return GTK_CONSTRAINT_RELATION_GE;
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
return relation;
|
||||
static unsigned int
|
||||
get_relation_id (GtkConstraintRelation relation)
|
||||
{
|
||||
switch (relation)
|
||||
{
|
||||
case GTK_CONSTRAINT_RELATION_LE: return 0;
|
||||
case GTK_CONSTRAINT_RELATION_EQ: return 1;
|
||||
case GTK_CONSTRAINT_RELATION_GE: return 2;
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
@@ -234,15 +261,29 @@ get_relation_display_name (GtkConstraintRelation relation)
|
||||
}
|
||||
|
||||
static GtkConstraintStrength
|
||||
get_strength (const char *id)
|
||||
{
|
||||
GtkConstraintStrength strength;
|
||||
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_STRENGTH);
|
||||
GEnumValue *value = g_enum_get_value_by_nick (class, id);
|
||||
strength = value->value;
|
||||
g_type_class_unref (class);
|
||||
get_strength (unsigned int id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case 0: return GTK_CONSTRAINT_STRENGTH_WEAK;
|
||||
case 1: return GTK_CONSTRAINT_STRENGTH_MEDIUM;
|
||||
case 2: return GTK_CONSTRAINT_STRENGTH_STRONG;
|
||||
case 3: return GTK_CONSTRAINT_STRENGTH_REQUIRED;
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
return strength;
|
||||
static unsigned int
|
||||
get_strength_id (GtkConstraintStrength strength)
|
||||
{
|
||||
switch (strength)
|
||||
{
|
||||
case GTK_CONSTRAINT_STRENGTH_WEAK: return 0;
|
||||
case GTK_CONSTRAINT_STRENGTH_MEDIUM: return 1;
|
||||
case GTK_CONSTRAINT_STRENGTH_STRONG: return 2;
|
||||
case GTK_CONSTRAINT_STRENGTH_REQUIRED: return 3;
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
@@ -294,7 +335,7 @@ static void
|
||||
create_constraint (GtkButton *button,
|
||||
ConstraintEditor *editor)
|
||||
{
|
||||
const char *id;
|
||||
gpointer obj;
|
||||
gpointer target;
|
||||
GtkConstraintAttribute target_attr;
|
||||
gpointer source;
|
||||
@@ -305,25 +346,27 @@ create_constraint (GtkButton *button,
|
||||
int strength;
|
||||
GtkConstraint *constraint;
|
||||
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target));
|
||||
target = get_target (editor->model, id);
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target_attr));
|
||||
target_attr = get_target_attr (id);
|
||||
obj = gtk_drop_down_get_selected_item (GTK_DROP_DOWN (editor->target));
|
||||
if (obj)
|
||||
target = get_target (editor->model, gtk_string_object_get_string (GTK_STRING_OBJECT (obj)));
|
||||
else
|
||||
target = NULL;
|
||||
target_attr = get_attr (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->target_attr)));
|
||||
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source));
|
||||
source = get_target (editor->model, id);
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source_attr));
|
||||
source_attr = get_target_attr (id);
|
||||
obj = gtk_drop_down_get_selected_item (GTK_DROP_DOWN (editor->source));
|
||||
if (obj)
|
||||
source = get_target (editor->model, gtk_string_object_get_string (GTK_STRING_OBJECT (obj)));
|
||||
else
|
||||
source = NULL;
|
||||
source_attr = get_attr (gtk_drop_down_get_selected (GTK_DROP_DOWN(editor->source_attr)));
|
||||
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->relation));
|
||||
relation = get_relation (id);
|
||||
relation = get_relation (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->relation)));
|
||||
|
||||
multiplier = g_ascii_strtod (gtk_editable_get_text (GTK_EDITABLE (editor->multiplier)), NULL);
|
||||
|
||||
constant = g_ascii_strtod (gtk_editable_get_text (GTK_EDITABLE (editor->constant)), NULL);
|
||||
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->strength));
|
||||
strength = get_strength (id);
|
||||
strength = get_strength (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->strength)));
|
||||
|
||||
constraint = gtk_constraint_new (target, target_attr,
|
||||
relation,
|
||||
@@ -338,12 +381,9 @@ create_constraint (GtkButton *button,
|
||||
static void
|
||||
source_attr_changed (ConstraintEditor *editor)
|
||||
{
|
||||
const char *id;
|
||||
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source_attr));
|
||||
if (strcmp (id, "none") == 0)
|
||||
if (get_attr (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->source_attr))) == GTK_CONSTRAINT_ATTRIBUTE_NONE)
|
||||
{
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (editor->source), -1);
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->source), GTK_INVALID_LIST_POSITION);
|
||||
gtk_editable_set_text (GTK_EDITABLE (editor->multiplier), "");
|
||||
gtk_widget_set_sensitive (editor->source, FALSE);
|
||||
gtk_widget_set_sensitive (editor->multiplier, FALSE);
|
||||
@@ -409,7 +449,7 @@ update_preview (ConstraintEditor *editor)
|
||||
GString *str;
|
||||
const char *name;
|
||||
const char *attr;
|
||||
char *relation;
|
||||
const char *relation;
|
||||
const char *multiplier;
|
||||
const char *constant;
|
||||
double c, m;
|
||||
@@ -419,23 +459,22 @@ update_preview (ConstraintEditor *editor)
|
||||
|
||||
str = g_string_new ("");
|
||||
|
||||
name = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target));
|
||||
attr = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target_attr));
|
||||
relation = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (editor->relation));
|
||||
name = gtk_string_object_get_string (GTK_STRING_OBJECT (gtk_drop_down_get_selected_item (GTK_DROP_DOWN (editor->target))));
|
||||
attr = get_attr_nick (get_attr (gtk_drop_down_get_selected ((GTK_DROP_DOWN (editor->target_attr)))));
|
||||
relation = get_relation_nick (get_relation (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->relation))));
|
||||
|
||||
if (name == NULL)
|
||||
name = "[ ]";
|
||||
|
||||
g_string_append_printf (str, "%s.%s %s ", name, attr, relation);
|
||||
g_free (relation);
|
||||
|
||||
constant = gtk_editable_get_text (GTK_EDITABLE (editor->constant));
|
||||
c = g_ascii_strtod (constant, NULL);
|
||||
|
||||
attr = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source_attr));
|
||||
attr = get_attr_nick (get_attr (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->source_attr))));
|
||||
if (strcmp (attr, "none") != 0)
|
||||
{
|
||||
name = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source));
|
||||
name = gtk_string_object_get_string (GTK_STRING_OBJECT (gtk_drop_down_get_selected_item (GTK_DROP_DOWN (editor->source))));
|
||||
multiplier = gtk_editable_get_text (GTK_EDITABLE (editor->multiplier));
|
||||
m = g_ascii_strtod (multiplier, NULL);
|
||||
|
||||
@@ -463,12 +502,18 @@ update_preview (ConstraintEditor *editor)
|
||||
static void
|
||||
update_button (ConstraintEditor *editor)
|
||||
{
|
||||
const char *target = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target));
|
||||
const char *source = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source));
|
||||
const char *source_attr = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source_attr));
|
||||
gpointer obj;
|
||||
const char *target;
|
||||
const char *source;
|
||||
GtkConstraintAttribute source_attr = get_attr (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->source_attr)));
|
||||
|
||||
if (target &&
|
||||
(source || (source_attr && get_target_attr (source_attr) == GTK_CONSTRAINT_ATTRIBUTE_NONE)))
|
||||
obj = gtk_drop_down_get_selected_item (GTK_DROP_DOWN (editor->target));
|
||||
target = obj ? gtk_string_object_get_string (GTK_STRING_OBJECT (obj)) : NULL;
|
||||
|
||||
obj = gtk_drop_down_get_selected_item (GTK_DROP_DOWN (editor->source));
|
||||
source = obj ? gtk_string_object_get_string (GTK_STRING_OBJECT (obj)) : NULL;
|
||||
|
||||
if (target && (source || (source_attr == GTK_CONSTRAINT_ATTRIBUTE_NONE)))
|
||||
gtk_widget_set_sensitive (editor->button, TRUE);
|
||||
else
|
||||
gtk_widget_set_sensitive (editor->button, FALSE);
|
||||
@@ -486,12 +531,7 @@ constraint_editor_constructed (GObject *object)
|
||||
ConstraintEditor *editor = CONSTRAINT_EDITOR (object);
|
||||
|
||||
constraint_target_combo (editor->model, editor->target, FALSE);
|
||||
constraint_attribute_combo (editor->target_attr, FALSE);
|
||||
constraint_relation_combo (editor->relation);
|
||||
constraint_target_combo (editor->model, editor->source, TRUE);
|
||||
constraint_attribute_combo (editor->source_attr, TRUE);
|
||||
|
||||
constraint_strength_combo (editor->strength);
|
||||
|
||||
if (editor->constraint)
|
||||
{
|
||||
@@ -499,30 +539,24 @@ constraint_editor_constructed (GObject *object)
|
||||
GtkConstraintAttribute attr;
|
||||
GtkConstraintRelation relation;
|
||||
GtkConstraintStrength strength;
|
||||
const char *nick;
|
||||
char *val;
|
||||
double multiplier;
|
||||
double constant;
|
||||
|
||||
target = gtk_constraint_get_target (editor->constraint);
|
||||
nick = get_target_name (target);
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->target), nick);
|
||||
select_target (GTK_DROP_DOWN (editor->target), get_target_name (target));
|
||||
|
||||
attr = gtk_constraint_get_target_attribute (editor->constraint);
|
||||
nick = get_attr_nick (attr);
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->target_attr), nick);
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->target_attr), get_attr_id (attr));
|
||||
|
||||
target = gtk_constraint_get_source (editor->constraint);
|
||||
nick = get_target_name (target);
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->source), nick);
|
||||
select_target (GTK_DROP_DOWN (editor->source), get_target_name (target));
|
||||
|
||||
attr = gtk_constraint_get_source_attribute (editor->constraint);
|
||||
nick = get_attr_nick (attr);
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->source_attr), nick);
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->source_attr), get_attr_id (attr));
|
||||
|
||||
relation = gtk_constraint_get_relation (editor->constraint);
|
||||
nick = get_relation_nick (relation);
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->relation), nick);
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->relation), get_relation_id (relation));
|
||||
|
||||
multiplier = gtk_constraint_get_multiplier (editor->constraint);
|
||||
val = g_strdup_printf ("%g", multiplier);
|
||||
@@ -535,17 +569,16 @@ constraint_editor_constructed (GObject *object)
|
||||
g_free (val);
|
||||
|
||||
strength = gtk_constraint_get_strength (editor->constraint);
|
||||
nick = get_strength_nick (strength);
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->strength), nick);
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->strength), get_strength_id (strength));
|
||||
|
||||
gtk_button_set_label (GTK_BUTTON (editor->button), "Apply");
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->target_attr), "left");
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->source_attr), "left");
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->relation), "eq");
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->strength), "required");
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->target_attr), get_attr_id (GTK_CONSTRAINT_ATTRIBUTE_LEFT));
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->source_attr), get_attr_id (GTK_CONSTRAINT_ATTRIBUTE_LEFT));
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->relation), get_relation_id (GTK_CONSTRAINT_RELATION_EQ));
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->strength), get_strength_id (GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
|
||||
gtk_editable_set_text (GTK_EDITABLE (editor->multiplier), "1.0");
|
||||
gtk_editable_set_text (GTK_EDITABLE (editor->constant), "0.0");
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkStringList" id="targets">
|
||||
<items>
|
||||
<item>None</item>
|
||||
<item>Left</item>
|
||||
<item>Right</item>
|
||||
<item>Top</item>
|
||||
<item>Bottom</item>
|
||||
<item>Start</item>
|
||||
<item>End</item>
|
||||
<item>Width</item>
|
||||
<item>Height</item>
|
||||
<item>Center X</item>
|
||||
<item>Center Y</item>
|
||||
<item>Baseline</item>
|
||||
</items>
|
||||
</object>
|
||||
<template class="ConstraintEditor" parent="GtkWidget">
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid">
|
||||
@@ -19,9 +35,9 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="target">
|
||||
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||
<signal name="changed" handler="update_button" swapped="yes"/>
|
||||
<object class="GtkDropDown" id="target">
|
||||
<signal name="notify::selected" handler="update_preview" swapped="yes"/>
|
||||
<signal name="notify::selected" handler="update_button" swapped="yes"/>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">1</property>
|
||||
@@ -29,8 +45,9 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="target_attr">
|
||||
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||
<object class="GtkDropDown" id="target_attr">
|
||||
<property name="model">targets</property>
|
||||
<signal name="notify::selected" handler="update_preview" swapped="yes"/>
|
||||
<layout>
|
||||
<property name="column">2</property>
|
||||
<property name="row">1</property>
|
||||
@@ -47,8 +64,17 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="relation">
|
||||
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||
<object class="GtkDropDown" id="relation">
|
||||
<signal name="notify::selected" handler="update_preview" swapped="yes"/>
|
||||
<property name="model">
|
||||
<object class="GtkStringList">
|
||||
<items>
|
||||
<item>≤</item>
|
||||
<item>=</item>
|
||||
<item>≥</item>
|
||||
</items>
|
||||
</object>
|
||||
</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">2</property>
|
||||
@@ -65,9 +91,9 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="source">
|
||||
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||
<signal name="changed" handler="update_button" swapped="yes"/>
|
||||
<object class="GtkDropDown" id="source">
|
||||
<signal name="notify::selected" handler="update_preview" swapped="yes"/>
|
||||
<signal name="notify::selected" handler="update_button" swapped="yes"/>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">3</property>
|
||||
@@ -75,10 +101,11 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="source_attr">
|
||||
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||
<signal name="changed" handler="source_attr_changed" swapped="yes"/>
|
||||
<signal name="changed" handler="update_button" swapped="yes"/>
|
||||
<object class="GtkDropDown" id="source_attr">
|
||||
<property name="model">targets</property>
|
||||
<signal name="notify::selected" handler="update_preview" swapped="yes"/>
|
||||
<signal name="notify::selected" handler="source_attr_changed" swapped="yes"/>
|
||||
<signal name="notify::selected" handler="update_button" swapped="yes"/>
|
||||
<layout>
|
||||
<property name="column">2</property>
|
||||
<property name="row">3</property>
|
||||
@@ -131,7 +158,17 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="strength">
|
||||
<object class="GtkDropDown" id="strength">
|
||||
<property name="model">
|
||||
<object class="GtkStringList">
|
||||
<items>
|
||||
<item>Weak</item>
|
||||
<item>Medium</item>
|
||||
<item>Strong</item>
|
||||
<item>Required</item>
|
||||
</items>
|
||||
</object>
|
||||
</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">6</property>
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
|
||||
#include "guide-editor.h"
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
struct _GuideEditor
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
@@ -59,25 +57,30 @@ static guint signals[LAST_SIGNAL];
|
||||
|
||||
G_DEFINE_TYPE(GuideEditor, guide_editor, GTK_TYPE_WIDGET);
|
||||
|
||||
static void
|
||||
guide_strength_combo (GtkWidget *combo)
|
||||
static GtkConstraintStrength
|
||||
get_strength (unsigned int id)
|
||||
{
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "weak", "Weak");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "medium", "Medium");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "strong", "Strong");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "required", "Required");
|
||||
switch (id)
|
||||
{
|
||||
case 0: return GTK_CONSTRAINT_STRENGTH_WEAK;
|
||||
case 1: return GTK_CONSTRAINT_STRENGTH_MEDIUM;
|
||||
case 2: return GTK_CONSTRAINT_STRENGTH_STRONG;
|
||||
case 3: return GTK_CONSTRAINT_STRENGTH_REQUIRED;
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static GtkConstraintStrength
|
||||
get_strength (const char *id)
|
||||
static unsigned int
|
||||
get_strength_id (GtkConstraintStrength strength)
|
||||
{
|
||||
GtkConstraintStrength strength;
|
||||
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_STRENGTH);
|
||||
GEnumValue *value = g_enum_get_value_by_nick (class, id);
|
||||
strength = value->value;
|
||||
g_type_class_unref (class);
|
||||
|
||||
return strength;
|
||||
switch (strength)
|
||||
{
|
||||
case GTK_CONSTRAINT_STRENGTH_WEAK: return 0;
|
||||
case GTK_CONSTRAINT_STRENGTH_MEDIUM: return 1;
|
||||
case GTK_CONSTRAINT_STRENGTH_STRONG: return 2;
|
||||
case GTK_CONSTRAINT_STRENGTH_REQUIRED: return 3;
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
@@ -118,11 +121,11 @@ static void
|
||||
create_guide (GtkButton *button,
|
||||
GuideEditor *editor)
|
||||
{
|
||||
const char *id;
|
||||
int strength;
|
||||
const char *name;
|
||||
int w, h;
|
||||
GtkConstraintGuide *guide;
|
||||
unsigned int id;
|
||||
|
||||
if (editor->guide)
|
||||
guide = g_object_ref (editor->guide);
|
||||
@@ -144,7 +147,7 @@ create_guide (GtkButton *button,
|
||||
h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->max_height));
|
||||
gtk_constraint_guide_set_max_size (guide, w, h);
|
||||
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->strength));
|
||||
id = gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->strength));
|
||||
strength = get_strength (id);
|
||||
gtk_constraint_guide_set_strength (guide, strength);
|
||||
|
||||
@@ -191,14 +194,9 @@ guide_editor_constructed (GObject *object)
|
||||
{
|
||||
GuideEditor *editor = GUIDE_EDITOR (object);
|
||||
|
||||
guide_strength_combo (editor->strength);
|
||||
|
||||
g_signal_connect (editor->min_width, "input", G_CALLBACK (min_input), NULL);
|
||||
|
||||
g_signal_connect (editor->min_height, "input", G_CALLBACK (min_input), NULL);
|
||||
|
||||
g_signal_connect (editor->max_width, "input", G_CALLBACK (max_input), NULL);
|
||||
|
||||
g_signal_connect (editor->max_height, "input", G_CALLBACK (max_input), NULL);
|
||||
|
||||
if (editor->guide)
|
||||
@@ -224,8 +222,7 @@ guide_editor_constructed (GObject *object)
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_height), h);
|
||||
|
||||
strength = gtk_constraint_guide_get_strength (editor->guide);
|
||||
nick = get_strength_nick (strength);
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->strength), nick);
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->strength), get_strength_id (strength));
|
||||
|
||||
gtk_button_set_label (GTK_BUTTON (editor->button), "Apply");
|
||||
}
|
||||
@@ -245,7 +242,7 @@ guide_editor_constructed (GObject *object)
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_width), G_MAXINT);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_height), G_MAXINT);
|
||||
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->strength), "medium");
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->strength), get_strength_id (GTK_CONSTRAINT_STRENGTH_MEDIUM));
|
||||
|
||||
gtk_button_set_label (GTK_BUTTON (editor->button), "Create");
|
||||
}
|
||||
|
||||
@@ -167,7 +167,17 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="strength">
|
||||
<object class="GtkDropDown" id="strength">
|
||||
<property name="model">
|
||||
<object class="GtkStringList">
|
||||
<items>
|
||||
<item>Weak</item>
|
||||
<item>Medium</item>
|
||||
<item>Strong</item>
|
||||
<item>Required</item>
|
||||
</items>
|
||||
</object>
|
||||
</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">4</property>
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
typedef GtkApplication DemoApplication;
|
||||
typedef GtkApplicationClass DemoApplicationClass;
|
||||
|
||||
@@ -216,6 +214,41 @@ activate_quit (GSimpleAction *action,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
delete_messages (gpointer data)
|
||||
{
|
||||
g_list_free_full ((GList *)data, g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
pop_message (GtkWidget *status)
|
||||
{
|
||||
GList *messages = (GList *) g_object_get_data (G_OBJECT (status), "messages");
|
||||
|
||||
if (messages)
|
||||
{
|
||||
char *message = messages->data;
|
||||
messages = g_list_remove (messages, message);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (status), "messages",
|
||||
messages, delete_messages);
|
||||
|
||||
gtk_label_set_label (GTK_LABEL (status), message);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
push_message (GtkWidget *status,
|
||||
const char *message)
|
||||
{
|
||||
GList *messages = (GList *) g_object_get_data (G_OBJECT (status), "messages");
|
||||
|
||||
gtk_label_set_label (GTK_LABEL (status), message);
|
||||
messages = g_list_prepend (messages, g_strdup (message));
|
||||
g_object_set_data_full (G_OBJECT (status), "messages",
|
||||
messages, delete_messages);
|
||||
}
|
||||
|
||||
static void
|
||||
update_statusbar (GtkTextBuffer *buffer,
|
||||
DemoApplicationWindow *window)
|
||||
@@ -226,7 +259,7 @@ update_statusbar (GtkTextBuffer *buffer,
|
||||
GtkTextIter iter;
|
||||
|
||||
/* clear any previous message, underflow is allowed */
|
||||
gtk_statusbar_pop (GTK_STATUSBAR (window->status), 0);
|
||||
pop_message (window->status);
|
||||
|
||||
count = gtk_text_buffer_get_char_count (buffer);
|
||||
|
||||
@@ -240,7 +273,7 @@ update_statusbar (GtkTextBuffer *buffer,
|
||||
msg = g_strdup_printf ("Cursor at row %d column %d - %d chars in document",
|
||||
row, col, count);
|
||||
|
||||
gtk_statusbar_push (GTK_STATUSBAR (window->status), 0, msg);
|
||||
push_message (window->status, msg);
|
||||
|
||||
g_free (msg);
|
||||
}
|
||||
|
||||
@@ -76,8 +76,13 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStatusbar" id="status">
|
||||
<object class="GtkLabel" id="status">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="margin-start">2</property>
|
||||
<property name="margin-end">2</property>
|
||||
<property name="margin-top">2</property>
|
||||
<property name="margin-bottom">2</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">3</property>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Builder
|
||||
* #Keywords: GMenu, GtkPopoverMenuBar, GtkBuilder, GtkStatusBar, GtkShortcutController, toolbar
|
||||
* #Keywords: GMenu, GtkPopoverMenuBar, GtkBuilder, GtkShortcutController, toolbar
|
||||
*
|
||||
* Demonstrates a traditional interface, loaded from a XML description,
|
||||
* and shows how to connect actions to the menu items and toolbar buttons.
|
||||
@@ -37,30 +37,34 @@ remove_timeout (gpointer data)
|
||||
g_source_remove (id);
|
||||
}
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static gboolean
|
||||
pop_status (gpointer data)
|
||||
static int
|
||||
pop_message (gpointer data)
|
||||
{
|
||||
gtk_statusbar_pop (GTK_STATUSBAR (data), 0);
|
||||
g_object_set_data (G_OBJECT (data), "timeout", NULL);
|
||||
GtkWidget *status = data;
|
||||
|
||||
gtk_label_set_label (GTK_LABEL (status), "");
|
||||
g_object_set_data (G_OBJECT (status), "timeout", GUINT_TO_POINTER (0));
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
status_message (GtkStatusbar *status,
|
||||
const char *text)
|
||||
status_message (GtkWidget *status,
|
||||
const char *text)
|
||||
{
|
||||
guint id;
|
||||
|
||||
gtk_statusbar_push (GTK_STATUSBAR (status), 0, text);
|
||||
id = g_timeout_add (5000, pop_status, status);
|
||||
id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (status), "timeout"));
|
||||
if (id)
|
||||
g_source_remove (id);
|
||||
|
||||
gtk_label_set_text (GTK_LABEL (status), text);
|
||||
|
||||
id = g_timeout_add (5000, pop_message, status);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (status), "timeout", GUINT_TO_POINTER (id), remove_timeout);
|
||||
}
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
static void
|
||||
help_activate (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
@@ -69,7 +73,7 @@ help_activate (GSimpleAction *action,
|
||||
GtkWidget *status;
|
||||
|
||||
status = GTK_WIDGET (g_object_get_data (G_OBJECT (user_data), "status"));
|
||||
status_message (GTK_STATUSBAR (status), "Help not available");
|
||||
status_message (status, "Help not available");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -82,7 +86,7 @@ not_implemented (GSimpleAction *action,
|
||||
|
||||
text = g_strdup_printf ("Action “%s” not implemented", g_action_get_name (G_ACTION (action)));
|
||||
status = GTK_WIDGET (g_object_get_data (G_OBJECT (user_data), "status"));
|
||||
status_message (GTK_STATUSBAR (status), text);
|
||||
status_message (status, text);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static void
|
||||
show_parsing_error (GtkCssProvider *provider,
|
||||
GtkCssSection *section,
|
||||
@@ -49,20 +47,23 @@ css_text_changed (GtkTextBuffer *buffer,
|
||||
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
|
||||
|
||||
text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
|
||||
gtk_css_provider_load_from_data (provider, text, -1);
|
||||
gtk_css_provider_load_from_string (provider, text);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
static void
|
||||
clear_provider (gpointer data)
|
||||
{
|
||||
GtkStyleProvider *provider = data;
|
||||
|
||||
gtk_style_context_remove_provider_for_display (gdk_display_get_default (), provider);
|
||||
}
|
||||
|
||||
static void
|
||||
apply_css (GtkWidget *widget, 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_add_provider_for_display (gdk_display_get_default (), provider, G_MAXUINT);
|
||||
g_object_set_data_full (G_OBJECT (widget), "provider", provider, clear_provider);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
@@ -81,6 +82,7 @@ do_css_basics (GtkWidget *do_widget)
|
||||
gtk_window_set_title (GTK_WINDOW (window), "CSS Basics");
|
||||
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
|
||||
gtk_widget_add_css_class (window, "demo");
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
text = gtk_text_buffer_new (NULL);
|
||||
|
||||
@@ -4,23 +4,24 @@
|
||||
* anymore. :)
|
||||
*/
|
||||
|
||||
/* This CSS resets all properties to their defaults values
|
||||
* and overrides all user settings and the theme in use */
|
||||
@import url("resource://css_basics/reset.css");
|
||||
/* This resets all properties to their defaults values
|
||||
* and overrides all user settings and the theme in use
|
||||
*/
|
||||
@import url("resource://css_shadows/reset.css");
|
||||
|
||||
/* Set a very futuristic style by default */
|
||||
* {
|
||||
.demo * {
|
||||
color: green;
|
||||
font-family: Monospace;
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
window {
|
||||
window.demo {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
/* Make sure selections are visible */
|
||||
selection {
|
||||
.demo selection {
|
||||
background-color: darkGreen;
|
||||
color: black;
|
||||
}
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static void
|
||||
show_parsing_error (GtkCssProvider *provider,
|
||||
GtkCssSection *section,
|
||||
@@ -50,33 +48,23 @@ css_text_changed (GtkTextBuffer *buffer,
|
||||
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
|
||||
|
||||
text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
|
||||
gtk_css_provider_load_from_data (provider, text, -1);
|
||||
gtk_css_provider_load_from_string (provider, text);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
static void
|
||||
drawing_area_draw (GtkDrawingArea *da,
|
||||
cairo_t *cr,
|
||||
int width,
|
||||
int height,
|
||||
gpointer data)
|
||||
clear_provider (gpointer data)
|
||||
{
|
||||
GtkStyleContext *context = gtk_widget_get_style_context (GTK_WIDGET (da));
|
||||
GtkStyleProvider *provider = data;
|
||||
|
||||
gtk_render_background (context, cr, 0, 0, width, height);
|
||||
gtk_render_frame (context, cr, 0, 0, width, height);
|
||||
gtk_style_context_remove_provider_for_display (gdk_display_get_default (), provider);
|
||||
}
|
||||
|
||||
static void
|
||||
apply_css (GtkWidget *widget, 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_add_provider_for_display (gdk_display_get_default (), provider, G_MAXUINT);
|
||||
g_object_set_data_full (G_OBJECT (widget), "provider", provider, clear_provider);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
@@ -95,16 +83,17 @@ do_css_multiplebgs (GtkWidget *do_widget)
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Multiple Backgrounds");
|
||||
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
|
||||
gtk_widget_add_css_class (window, "demo");
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
overlay = gtk_overlay_new ();
|
||||
gtk_window_set_child (GTK_WINDOW (window), overlay);
|
||||
|
||||
child = gtk_drawing_area_new ();
|
||||
/* Don't set a draw_func, since we are only interested in CSS drawing,
|
||||
* which happens automatically.
|
||||
*/
|
||||
gtk_widget_set_name (child, "canvas");
|
||||
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (child),
|
||||
drawing_area_draw,
|
||||
NULL, NULL);
|
||||
gtk_overlay_set_child (GTK_OVERLAY (overlay), child);
|
||||
|
||||
child = gtk_button_new ();
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static void
|
||||
show_parsing_error (GtkCssProvider *provider,
|
||||
GtkCssSection *section,
|
||||
@@ -51,20 +49,23 @@ css_text_changed (GtkTextBuffer *buffer,
|
||||
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
|
||||
|
||||
text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
|
||||
gtk_css_provider_load_from_data (provider, text, -1);
|
||||
gtk_css_provider_load_from_string (provider, text);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
static void
|
||||
clear_provider (gpointer data)
|
||||
{
|
||||
GtkStyleProvider *provider = data;
|
||||
|
||||
gtk_style_context_remove_provider_for_display (gdk_display_get_default (), provider);
|
||||
}
|
||||
|
||||
static void
|
||||
apply_css (GtkWidget *widget, 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_add_provider_for_display (gdk_display_get_default (), provider, G_MAXUINT);
|
||||
g_object_set_data_full (G_OBJECT (widget), "provider", provider, clear_provider);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
@@ -83,6 +84,7 @@ do_css_pixbufs (GtkWidget *do_widget)
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Animated Backgrounds");
|
||||
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
|
||||
gtk_widget_add_css_class (window, "demo");
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
paned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
100% { background-size: 12px, 96px, 12px, 96px, 12px, 96px, 12px, 96px, auto; }
|
||||
}
|
||||
|
||||
window {
|
||||
window.demo {
|
||||
background-image: url("resource://css_pixbufs/images/apple-red.png"),
|
||||
url("resource://css_pixbufs/images/gnome-applets.png"),
|
||||
url("resource://css_pixbufs/images/gnome-calendar.png"),
|
||||
@@ -66,11 +66,11 @@ window {
|
||||
}
|
||||
|
||||
/* Make the text editor has a nice style */
|
||||
.view, scrollbar, separator {
|
||||
window.demo .view, scrollbar, separator {
|
||||
color: black;
|
||||
background-color: rgba(255,255,255,0.5);
|
||||
}
|
||||
|
||||
.view:selected {
|
||||
window.demo .view:selected {
|
||||
background-color: rgba(127,127,255,0.5);
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static void
|
||||
show_parsing_error (GtkCssProvider *provider,
|
||||
GtkCssSection *section,
|
||||
@@ -48,20 +46,23 @@ css_text_changed (GtkTextBuffer *buffer,
|
||||
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
|
||||
|
||||
text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
|
||||
gtk_css_provider_load_from_data (provider, text, -1);
|
||||
gtk_css_provider_load_from_string (provider, text);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
static void
|
||||
clear_provider (gpointer data)
|
||||
{
|
||||
GtkStyleProvider *provider = data;
|
||||
|
||||
gtk_style_context_remove_provider_for_display (gdk_display_get_default (), provider);
|
||||
}
|
||||
|
||||
static void
|
||||
apply_css (GtkWidget *widget, 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_add_provider_for_display (gdk_display_get_default (), provider, G_MAXUINT);
|
||||
g_object_set_data_full (G_OBJECT (widget), "provider", provider, clear_provider);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
@@ -101,6 +102,7 @@ do_css_shadows (GtkWidget *do_widget)
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Shadows");
|
||||
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
|
||||
gtk_widget_add_css_class (window, "demo");
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
paned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
|
||||
@@ -142,7 +144,7 @@ do_css_shadows (GtkWidget *do_widget)
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_set_visible (window, TRUE);
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
|
||||
|
||||
@@ -5,12 +5,13 @@
|
||||
*/
|
||||
|
||||
/* This CSS resets all properties to their defaults values
|
||||
* and overrides all user settings and the theme in use */
|
||||
* and overrides all user settings and the theme in use
|
||||
*/
|
||||
@import url("resource://css_shadows/reset.css");
|
||||
@import url("resource://css_shadows/cssview.css");
|
||||
|
||||
/* Get a nice background for the window */
|
||||
.background {
|
||||
window.demo.background {
|
||||
background-color: #4870bc;
|
||||
background-image: linear-gradient(to left, transparent, rgba(255,255,255,.07) 50%, transparent 50%),
|
||||
linear-gradient(to left, transparent, rgba(255,255,255,.13) 50%, transparent 50%),
|
||||
@@ -19,7 +20,7 @@
|
||||
background-size: 29px, 59px, 73px, 109px;
|
||||
}
|
||||
|
||||
button {
|
||||
window.demo button {
|
||||
color: black;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
@@ -27,18 +28,15 @@ button {
|
||||
border: 1px transparent solid;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
window.demo button:hover {
|
||||
text-shadow: 3px 3px 5px alpha(black, 0.75);
|
||||
-gtk-icon-shadow: 3px 3px 5px alpha(black, 0.75);
|
||||
box-shadow: 3px 3px 5px alpha(black, 0.5) inset;
|
||||
border: solid 1px alpha(black, 0.75);
|
||||
}
|
||||
|
||||
button:active {
|
||||
window.demo button:active {
|
||||
padding: 11px 9px 9px 11px;
|
||||
text-shadow: 1px 1px 2.5px alpha(black, 0.6);
|
||||
-gtk-icon-shadow: 1px 1px 2.5px alpha(black, 0.6);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
/* Make the text editor has a nice style */
|
||||
.view {
|
||||
window.demo .view {
|
||||
color: #2e3436;
|
||||
font-family: Monospace;
|
||||
background-color: alpha(white, 0.30);
|
||||
}
|
||||
|
||||
.view:selected {
|
||||
window.demo .view:selected {
|
||||
color: white;
|
||||
background-color: #4a90d9;
|
||||
}
|
||||
|
||||
scrollbar trough,
|
||||
window.demo scrollbar trough,
|
||||
.scrollbars-junction {
|
||||
background-color: alpha(white, 0.80);
|
||||
}
|
||||
|
||||
scrollbar slider {
|
||||
window.demo scrollbar slider {
|
||||
border-width: 3px;
|
||||
border-style: solid;
|
||||
border-radius: 10px;
|
||||
@@ -24,11 +24,11 @@ scrollbar slider {
|
||||
background-color: #999;
|
||||
}
|
||||
|
||||
scrollbar slider:hover {
|
||||
window.demo scrollbar slider:hover {
|
||||
background-color: #555;
|
||||
}
|
||||
|
||||
paned separator {
|
||||
window.demo paned separator {
|
||||
background-color: alpha(white, 0.80);
|
||||
background-image: linear-gradient(transparent, transparent 1px, #999 1px, #999 4px, transparent 4px);
|
||||
background-size: 40px auto;
|
||||
@@ -36,6 +36,6 @@ paned separator {
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
paned separator:hover {
|
||||
window.demo paned separator:hover {
|
||||
background-image: linear-gradient(transparent, transparent 1px, #555 1px, #555 4px, transparent 4px);
|
||||
}
|
||||
|
||||
@@ -335,6 +335,8 @@
|
||||
<file>paintable_symbolic.c</file>
|
||||
<file>panes.c</file>
|
||||
<file>password_entry.c</file>
|
||||
<file>path_fill.c</file>
|
||||
<file>path_text.c</file>
|
||||
<file>peg_solitaire.c</file>
|
||||
<file>pickers.c</file>
|
||||
<file>printing.c</file>
|
||||
@@ -420,6 +422,9 @@
|
||||
<gresource prefix="/fontrendering">
|
||||
<file>fontrendering.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/path_text">
|
||||
<file>path_text.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/org/gtk/Demo4">
|
||||
<file>icons/16x16/actions/application-exit.png</file>
|
||||
<file>icons/16x16/actions/document-new.png</file>
|
||||
|
||||
@@ -208,7 +208,13 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStatusbar" id="statusbar1"/>
|
||||
<object class="GtkLabel" id="statusbar1">
|
||||
<property name="xalign">0</property>
|
||||
<property name="margin-start">2</property>
|
||||
<property name="margin-end">2</property>
|
||||
<property name="margin-top">2</property>
|
||||
<property name="margin-bottom">2</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@@ -760,9 +760,7 @@ do_dnd (GtkWidget *do_widget)
|
||||
GtkCssProvider *provider;
|
||||
GString *css;
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
button = gtk_color_button_new ();
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
button = gtk_color_dialog_button_new (gtk_color_dialog_new ());
|
||||
g_object_unref (g_object_ref_sink (button));
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
static void
|
||||
@@ -45,21 +43,22 @@ do_expander (GtkWidget *do_widget)
|
||||
if (!window)
|
||||
{
|
||||
toplevel = GTK_WIDGET (gtk_widget_get_root (do_widget));
|
||||
window = gtk_message_dialog_new_with_markup (GTK_WINDOW (toplevel),
|
||||
0,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_CLOSE,
|
||||
"<big><b>%s</b></big>",
|
||||
"Something went wrong");
|
||||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (window),
|
||||
"Here are some more details "
|
||||
"but not the full story.");
|
||||
|
||||
area = gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG (window));
|
||||
|
||||
label = gtk_widget_get_last_child (area);
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Expander");
|
||||
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (toplevel));
|
||||
area = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
|
||||
gtk_widget_set_margin_start (area, 10);
|
||||
gtk_widget_set_margin_end (area, 10);
|
||||
gtk_widget_set_margin_top (area, 10);
|
||||
gtk_widget_set_margin_bottom (area, 10);
|
||||
gtk_window_set_child (GTK_WINDOW (window), area);
|
||||
label = gtk_label_new ("<big><b>Something went wrong</b></big>");
|
||||
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
|
||||
gtk_box_append (GTK_BOX (area), label);
|
||||
label = gtk_label_new ("Here are some more details but not the full story");
|
||||
gtk_label_set_wrap (GTK_LABEL (label), FALSE);
|
||||
gtk_widget_set_vexpand (label, FALSE);
|
||||
gtk_box_append (GTK_BOX (area), label);
|
||||
|
||||
expander = gtk_expander_new ("Details:");
|
||||
gtk_widget_set_vexpand (expander, TRUE);
|
||||
@@ -122,7 +121,7 @@ do_expander (GtkWidget *do_widget)
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_set_visible (window, TRUE);
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
|
||||
|
||||
@@ -68,13 +68,18 @@ create_blurred_button (void)
|
||||
return w;
|
||||
}
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
static GtkWidget *
|
||||
create_font_button (void)
|
||||
{
|
||||
return gtk_font_button_new ();
|
||||
GtkFontDialog *dialog;
|
||||
GtkWidget *button;
|
||||
|
||||
dialog = gtk_font_dialog_new ();
|
||||
button = gtk_font_dialog_button_new (dialog);
|
||||
g_object_unref (dialog);
|
||||
|
||||
return button;
|
||||
}
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
static GtkWidget *
|
||||
create_level_bar (void)
|
||||
@@ -310,11 +315,20 @@ do_fishbowl (GtkWidget *do_widget)
|
||||
if (!window)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
GtkBuilderScope *scope;
|
||||
GtkWidget *bowl;
|
||||
|
||||
g_type_ensure (GTK_TYPE_FISHBOWL);
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/fishbowl/fishbowl.ui");
|
||||
scope = gtk_builder_cscope_new ();
|
||||
gtk_builder_cscope_add_callback (GTK_BUILDER_CSCOPE (scope), fishbowl_prev_button_clicked_cb);
|
||||
gtk_builder_cscope_add_callback (GTK_BUILDER_CSCOPE (scope), fishbowl_next_button_clicked_cb);
|
||||
gtk_builder_cscope_add_callback (GTK_BUILDER_CSCOPE (scope), fishbowl_changes_toggled_cb);
|
||||
gtk_builder_cscope_add_callback (GTK_BUILDER_CSCOPE (scope), format_header_cb);
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_set_scope (builder, scope);
|
||||
gtk_builder_add_from_resource (builder, "/fishbowl/fishbowl.ui", NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
@@ -326,6 +340,7 @@ do_fishbowl (GtkWidget *do_widget)
|
||||
|
||||
gtk_widget_realize (window);
|
||||
g_object_unref (builder);
|
||||
g_object_unref (scope);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -354,10 +354,18 @@ do_iconscroll (GtkWidget *do_widget)
|
||||
if (!window)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
GtkBuilderScope *scope;
|
||||
GtkWidget *label;
|
||||
guint id;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/iconscroll/iconscroll.ui");
|
||||
scope = gtk_builder_cscope_new ();
|
||||
gtk_builder_cscope_add_callback (GTK_BUILDER_CSCOPE (scope), iconscroll_prev_clicked_cb);
|
||||
gtk_builder_cscope_add_callback (GTK_BUILDER_CSCOPE (scope), iconscroll_next_clicked_cb);
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_set_scope (builder, scope);
|
||||
|
||||
gtk_builder_add_from_resource (builder, "/iconscroll/iconscroll.ui", NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
@@ -375,6 +383,7 @@ do_iconscroll (GtkWidget *do_widget)
|
||||
GUINT_TO_POINTER (id), remove_timeout);
|
||||
|
||||
g_object_unref (builder);
|
||||
g_object_unref (scope);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -72,6 +72,8 @@ demos = files([
|
||||
'paintable_symbolic.c',
|
||||
'panes.c',
|
||||
'password_entry.c',
|
||||
'path_fill.c',
|
||||
'path_text.c',
|
||||
'peg_solitaire.c',
|
||||
'pickers.c',
|
||||
'printing.c',
|
||||
@@ -150,8 +152,6 @@ if librsvg_dep.found()
|
||||
gtkdemo_deps += [ librsvg_dep ]
|
||||
endif
|
||||
|
||||
gtkdemo_args = [ '-DGDK_DISABLE_DEPRECATED', '-DGTK_DISABLE_DEPRECATED', ]
|
||||
|
||||
demos_h = custom_target('gtk4 demo header',
|
||||
output: 'demos.h',
|
||||
input: demos,
|
||||
@@ -206,6 +206,7 @@ if can_use_objcopy_for_resources
|
||||
output : 'gtkdemo_resources2.o',
|
||||
command : [objcopy,
|
||||
'--strip-all',
|
||||
'--set-section-alignment', '.data=8',
|
||||
'--add-symbol','_g_binary_gtkdemo_resource_data=.data:0',
|
||||
'@INPUT@',
|
||||
'@OUTPUT@'])
|
||||
@@ -234,7 +235,7 @@ gtkdemo_deps += [ demo_conf_h ]
|
||||
|
||||
executable('gtk4-demo',
|
||||
sources: [demos, demos_h, extra_demo_sources, gtkdemo_resources],
|
||||
c_args: gtkdemo_args + demo_cflags,
|
||||
c_args: demo_cflags,
|
||||
dependencies: gtkdemo_deps,
|
||||
include_directories: confinc,
|
||||
win_subsystem: 'windows',
|
||||
@@ -244,7 +245,7 @@ executable('gtk4-demo',
|
||||
|
||||
executable('gtk4-demo-application',
|
||||
sources: ['application.c', gtkdemo_resources],
|
||||
c_args: gtkdemo_args + common_cflags,
|
||||
c_args: common_cflags,
|
||||
dependencies: gtkdemo_deps,
|
||||
include_directories: confinc,
|
||||
win_subsystem: 'windows',
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
enum {
|
||||
COLOR_SET,
|
||||
N_SIGNALS
|
||||
@@ -124,19 +122,16 @@ drawing_area_unmap (GtkWidget *widget)
|
||||
|
||||
static void
|
||||
drawing_area_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
DrawingArea *area = (DrawingArea *) widget;
|
||||
GtkAllocation allocation;
|
||||
int width, height;
|
||||
cairo_t *cr;
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
cr = gtk_snapshot_append_cairo (snapshot,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
0, 0,
|
||||
allocation.width,
|
||||
allocation.height
|
||||
));
|
||||
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));
|
||||
|
||||
cairo_set_source_rgb (cr, 1, 1, 1);
|
||||
cairo_paint (cr);
|
||||
@@ -145,7 +140,7 @@ drawing_area_snapshot (GtkWidget *widget,
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_set_source_rgb (cr, 0.6, 0.6, 0.6);
|
||||
cairo_rectangle (cr, 0, 0, allocation.width, allocation.height);
|
||||
cairo_rectangle (cr, 0, 0, width, height);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_destroy (cr);
|
||||
|
||||
198
demos/gtk-demo/path_fill.c
Normal file
198
demos/gtk-demo/path_fill.c
Normal file
@@ -0,0 +1,198 @@
|
||||
/* Path/Fill and Stroke
|
||||
*
|
||||
* This demo shows how to use GskPath to draw shapes that are (a bit)
|
||||
* more complex than a rounded rectangle.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "paintable.h"
|
||||
|
||||
#define GTK_TYPE_LOGO_PAINTABLE (gtk_logo_paintable_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (GtkLogoPaintable, gtk_logo_paintable, GTK, LOGO_PAINTABLE, GObject)
|
||||
|
||||
struct _GtkLogoPaintable
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
GskPath *path[3];
|
||||
GdkRGBA color[3];
|
||||
|
||||
GskPath *stroke_path;
|
||||
GskStroke *stroke1;
|
||||
GskStroke *stroke2;
|
||||
GdkRGBA stroke_color;
|
||||
};
|
||||
|
||||
struct _GtkLogoPaintableClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
static int
|
||||
gtk_logo_paintable_get_intrinsic_width (GdkPaintable *paintable)
|
||||
{
|
||||
GtkLogoPaintable *self = GTK_LOGO_PAINTABLE (paintable);
|
||||
|
||||
return self->width;
|
||||
}
|
||||
|
||||
static int
|
||||
gtk_logo_paintable_get_intrinsic_height (GdkPaintable *paintable)
|
||||
{
|
||||
GtkLogoPaintable *self = GTK_LOGO_PAINTABLE (paintable);
|
||||
|
||||
return self->height;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_logo_paintable_snapshot (GdkPaintable *paintable,
|
||||
GdkSnapshot *snapshot,
|
||||
double width,
|
||||
double height)
|
||||
{
|
||||
GtkLogoPaintable *self = GTK_LOGO_PAINTABLE (paintable);
|
||||
|
||||
for (unsigned int i = 0; i < 3; i++)
|
||||
{
|
||||
gtk_snapshot_push_fill (snapshot, self->path[i], GSK_FILL_RULE_WINDING);
|
||||
gtk_snapshot_append_color (snapshot,
|
||||
&self->color[i],
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
for (unsigned int i = 0; i < 3; i++)
|
||||
{
|
||||
gtk_snapshot_push_stroke (snapshot, self->stroke_path, self->stroke1);
|
||||
gtk_snapshot_append_color (snapshot,
|
||||
&self->stroke_color,
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
|
||||
gtk_snapshot_push_stroke (snapshot, self->stroke_path, self->stroke2);
|
||||
gtk_snapshot_append_color (snapshot,
|
||||
&self->stroke_color,
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
|
||||
static GdkPaintableFlags
|
||||
gtk_logo_paintable_get_flags (GdkPaintable *paintable)
|
||||
{
|
||||
return GDK_PAINTABLE_STATIC_CONTENTS | GDK_PAINTABLE_STATIC_SIZE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_logo_paintable_paintable_init (GdkPaintableInterface *iface)
|
||||
{
|
||||
iface->get_intrinsic_width = gtk_logo_paintable_get_intrinsic_width;
|
||||
iface->get_intrinsic_height = gtk_logo_paintable_get_intrinsic_height;
|
||||
iface->snapshot = gtk_logo_paintable_snapshot;
|
||||
iface->get_flags = gtk_logo_paintable_get_flags;
|
||||
}
|
||||
|
||||
/* When defining the GType, we need to implement the GdkPaintable interface */
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkLogoPaintable, gtk_logo_paintable, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
|
||||
gtk_logo_paintable_paintable_init))
|
||||
|
||||
static void
|
||||
gtk_logo_paintable_dispose (GObject *object)
|
||||
{
|
||||
GtkLogoPaintable *self = GTK_LOGO_PAINTABLE (object);
|
||||
|
||||
for (unsigned int i = 0; i < 3; i++)
|
||||
gsk_path_unref (self->path[i]);
|
||||
|
||||
gsk_path_unref (self->stroke_path);
|
||||
|
||||
gsk_stroke_free (self->stroke1);
|
||||
gsk_stroke_free (self->stroke2);
|
||||
|
||||
G_OBJECT_CLASS (gtk_logo_paintable_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_logo_paintable_class_init (GtkLogoPaintableClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gtk_logo_paintable_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_logo_paintable_init (GtkLogoPaintable *self)
|
||||
{
|
||||
}
|
||||
|
||||
static GdkPaintable *
|
||||
gtk_logo_paintable_new (void)
|
||||
{
|
||||
GtkLogoPaintable *self;
|
||||
graphene_rect_t bounds, bounds2;
|
||||
|
||||
self = g_object_new (GTK_TYPE_LOGO_PAINTABLE, NULL);
|
||||
|
||||
/* Paths and colors extracted from gtk-logo.svg */
|
||||
self->path[0] = gsk_path_parse ("m3.12,66.17 -2.06,-51.46 32.93,24.7 v55.58 l-30.87,-28.82 z");
|
||||
self->path[1] = gsk_path_parse ("m34,95 49.4,-20.58 4.12,-51.46 -53.52,16.47 v55.58 z");
|
||||
self->path[2] = gsk_path_parse ("m1.06,14.71 32.93,24.7 53.52,-16.47 -36.75,-21.88 -49.7,13.65 z");
|
||||
|
||||
gdk_rgba_parse (&self->color[0], "#e40000");
|
||||
gdk_rgba_parse (&self->color[1], "#7fe719");
|
||||
gdk_rgba_parse (&self->color[2], "#729fcf");
|
||||
|
||||
self->stroke_path = gsk_path_parse ("m50.6,51.3 -47.3,14 z l33,23 z v-50");
|
||||
self->stroke1 = gsk_stroke_new (2.12);
|
||||
self->stroke2 = gsk_stroke_new (1.25);
|
||||
gdk_rgba_parse (&self->stroke_color, "#ffffff");
|
||||
|
||||
gsk_path_get_stroke_bounds (self->path[0], self->stroke1, &bounds);
|
||||
gsk_path_get_stroke_bounds (self->path[1], self->stroke1, &bounds2);
|
||||
graphene_rect_union (&bounds, &bounds2, &bounds);
|
||||
gsk_path_get_stroke_bounds (self->path[2], self->stroke1, &bounds2);
|
||||
graphene_rect_union (&bounds, &bounds2, &bounds);
|
||||
gsk_path_get_stroke_bounds (self->stroke_path, self->stroke2, &bounds2);
|
||||
graphene_rect_union (&bounds, &bounds2, &bounds);
|
||||
|
||||
self->width = bounds.origin.x + bounds.size.width;
|
||||
self->height = bounds.origin.y + bounds.size.height;
|
||||
|
||||
return GDK_PAINTABLE (self);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_path_fill (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *picture;
|
||||
GdkPaintable *paintable;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Path Fill");
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
paintable = gtk_logo_paintable_new ();
|
||||
picture = gtk_picture_new_for_paintable (paintable);
|
||||
gtk_picture_set_content_fit (GTK_PICTURE (picture), GTK_CONTENT_FIT_CONTAIN);
|
||||
gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE);
|
||||
g_object_unref (paintable);
|
||||
|
||||
gtk_window_set_child (GTK_WINDOW (window), picture);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
|
||||
return window;
|
||||
}
|
||||
604
demos/gtk-demo/path_text.c
Normal file
604
demos/gtk-demo/path_text.c
Normal file
@@ -0,0 +1,604 @@
|
||||
/* Path/Text
|
||||
*
|
||||
* This demo shows how to use GskPath to animate a path along another path.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define GTK_TYPE_PATH_WIDGET (gtk_path_widget_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (GtkPathWidget, gtk_path_widget, GTK, PATH_WIDGET, GtkWidget)
|
||||
|
||||
#define POINT_SIZE 8
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_TEXT,
|
||||
PROP_EDITABLE,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
struct _GtkPathWidget
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
char *text;
|
||||
gboolean editable;
|
||||
|
||||
graphene_point_t points[4];
|
||||
|
||||
guint active_point;
|
||||
float line_closest;
|
||||
|
||||
GskPath *line_path;
|
||||
GskPathMeasure *line_measure;
|
||||
GskPath *text_path;
|
||||
|
||||
GdkPaintable *background;
|
||||
};
|
||||
|
||||
struct _GtkPathWidgetClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
static GParamSpec *properties[N_PROPS] = { NULL, };
|
||||
|
||||
G_DEFINE_TYPE (GtkPathWidget, gtk_path_widget, GTK_TYPE_WIDGET)
|
||||
|
||||
static GskPath *
|
||||
create_path_from_text (GtkWidget *widget,
|
||||
const char *text,
|
||||
graphene_point_t *out_offset)
|
||||
{
|
||||
PangoLayout *layout;
|
||||
PangoFontDescription *desc;
|
||||
GskPathBuilder *builder;
|
||||
GskPath *result;
|
||||
|
||||
layout = gtk_widget_create_pango_layout (widget, text);
|
||||
desc = pango_font_description_from_string ("sans bold 36");
|
||||
pango_layout_set_font_description (layout, desc);
|
||||
pango_font_description_free (desc);
|
||||
|
||||
builder = gsk_path_builder_new ();
|
||||
gsk_path_builder_add_layout (builder, layout);
|
||||
result = gsk_path_builder_free_to_path (builder);
|
||||
|
||||
if (out_offset)
|
||||
graphene_point_init (out_offset, 0, - pango_layout_get_baseline (layout) / (double) PANGO_SCALE);
|
||||
g_object_unref (layout);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GskPathMeasure *measure;
|
||||
GskPathBuilder *builder;
|
||||
graphene_point_t offset;
|
||||
double scale;
|
||||
} GtkPathTransform;
|
||||
|
||||
static void
|
||||
gtk_path_transform_point (GskPathMeasure *measure,
|
||||
const graphene_point_t *pt,
|
||||
const graphene_point_t *offset,
|
||||
float scale,
|
||||
graphene_point_t *res)
|
||||
{
|
||||
graphene_vec2_t tangent;
|
||||
GskPathPoint point;
|
||||
|
||||
if (gsk_path_measure_get_point (measure, (pt->x + offset->x) * scale, &point))
|
||||
{
|
||||
GskPath *path = gsk_path_measure_get_path (measure);
|
||||
|
||||
gsk_path_point_get_position (path, &point, res);
|
||||
gsk_path_point_get_tangent (path, &point, GSK_PATH_END, &tangent);
|
||||
|
||||
res->x -= (pt->y + offset->y) * scale * graphene_vec2_get_y (&tangent);
|
||||
res->y += (pt->y + offset->y) * scale * graphene_vec2_get_x (&tangent);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_path_transform_op (GskPathOperation op,
|
||||
const graphene_point_t *pts,
|
||||
gsize n_pts,
|
||||
gpointer data)
|
||||
{
|
||||
GtkPathTransform *transform = data;
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case GSK_PATH_MOVE:
|
||||
{
|
||||
graphene_point_t res;
|
||||
gtk_path_transform_point (transform->measure, &pts[0], &transform->offset, transform->scale, &res);
|
||||
gsk_path_builder_move_to (transform->builder, res.x, res.y);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_PATH_LINE:
|
||||
{
|
||||
graphene_point_t res;
|
||||
gtk_path_transform_point (transform->measure, &pts[1], &transform->offset, transform->scale, &res);
|
||||
gsk_path_builder_line_to (transform->builder, res.x, res.y);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_PATH_QUAD:
|
||||
{
|
||||
graphene_point_t res[2];
|
||||
gtk_path_transform_point (transform->measure, &pts[1], &transform->offset, transform->scale, &res[0]);
|
||||
gtk_path_transform_point (transform->measure, &pts[2], &transform->offset, transform->scale, &res[1]);
|
||||
gsk_path_builder_quad_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_PATH_CUBIC:
|
||||
{
|
||||
graphene_point_t res[3];
|
||||
gtk_path_transform_point (transform->measure, &pts[1], &transform->offset, transform->scale, &res[0]);
|
||||
gtk_path_transform_point (transform->measure, &pts[2], &transform->offset, transform->scale, &res[1]);
|
||||
gtk_path_transform_point (transform->measure, &pts[3], &transform->offset, transform->scale, &res[2]);
|
||||
gsk_path_builder_cubic_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y, res[2].x, res[2].y);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_PATH_CLOSE:
|
||||
gsk_path_builder_close (transform->builder);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GskPath *
|
||||
gtk_path_transform (GskPathMeasure *measure,
|
||||
GskPath *path,
|
||||
const graphene_point_t *offset)
|
||||
{
|
||||
GtkPathTransform transform = { measure, gsk_path_builder_new (), *offset };
|
||||
graphene_rect_t bounds;
|
||||
|
||||
gsk_path_get_bounds (path, &bounds);
|
||||
if (bounds.origin.x + bounds.size.width > 0)
|
||||
transform.scale = gsk_path_measure_get_length (measure) / (bounds.origin.x + bounds.size.width);
|
||||
else
|
||||
transform.scale = 1.0f;
|
||||
|
||||
gsk_path_foreach (path, -1, gtk_path_transform_op, &transform);
|
||||
|
||||
return gsk_path_builder_free_to_path (transform.builder);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_clear_text_path (GtkPathWidget *self)
|
||||
{
|
||||
g_clear_pointer (&self->text_path, gsk_path_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_clear_paths (GtkPathWidget *self)
|
||||
{
|
||||
gtk_path_widget_clear_text_path (self);
|
||||
|
||||
g_clear_pointer (&self->line_path, gsk_path_unref);
|
||||
g_clear_pointer (&self->line_measure, gsk_path_measure_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_create_text_path (GtkPathWidget *self)
|
||||
{
|
||||
GskPath *path;
|
||||
graphene_point_t offset;
|
||||
|
||||
gtk_path_widget_clear_text_path (self);
|
||||
|
||||
if (self->line_measure == NULL)
|
||||
return;
|
||||
|
||||
path = create_path_from_text (GTK_WIDGET (self), self->text, &offset);
|
||||
self->text_path = gtk_path_transform (self->line_measure, path, &offset);
|
||||
|
||||
gsk_path_unref (path);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_create_paths (GtkPathWidget *self)
|
||||
{
|
||||
double width = gtk_widget_get_width (GTK_WIDGET (self));
|
||||
double height = gtk_widget_get_height (GTK_WIDGET (self));
|
||||
GskPathBuilder *builder;
|
||||
|
||||
gtk_path_widget_clear_paths (self);
|
||||
|
||||
if (width <= 0 || height <= 0)
|
||||
return;
|
||||
|
||||
builder = gsk_path_builder_new ();
|
||||
gsk_path_builder_move_to (builder,
|
||||
self->points[0].x * width, self->points[0].y * height);
|
||||
gsk_path_builder_cubic_to (builder,
|
||||
self->points[1].x * width, self->points[1].y * height,
|
||||
self->points[2].x * width, self->points[2].y * height,
|
||||
self->points[3].x * width, self->points[3].y * height);
|
||||
self->line_path = gsk_path_builder_free_to_path (builder);
|
||||
|
||||
self->line_measure = gsk_path_measure_new (self->line_path);
|
||||
|
||||
gtk_path_widget_create_text_path (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
GtkPathWidget *self = GTK_PATH_WIDGET (widget);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_path_widget_parent_class)->size_allocate (widget, width, height, baseline);
|
||||
|
||||
gtk_path_widget_create_paths (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
GtkPathWidget *self = GTK_PATH_WIDGET (widget);
|
||||
double width = gtk_widget_get_width (widget);
|
||||
double height = gtk_widget_get_height (widget);
|
||||
GskPath *path;
|
||||
GskStroke *stroke;
|
||||
gsize i;
|
||||
|
||||
/* frosted glass the background */
|
||||
gtk_snapshot_push_blur (snapshot, 100);
|
||||
gdk_paintable_snapshot (self->background, snapshot, width, height);
|
||||
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 1, 1, 1, 0.6 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
gtk_snapshot_pop (snapshot);
|
||||
|
||||
/* draw the text */
|
||||
if (self->text_path)
|
||||
{
|
||||
gtk_snapshot_push_fill (snapshot, self->text_path, GSK_FILL_RULE_WINDING);
|
||||
gdk_paintable_snapshot (self->background, snapshot, width, height);
|
||||
|
||||
/* ... with an emboss effect */
|
||||
stroke = gsk_stroke_new (2.0);
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT(1, 1));
|
||||
gtk_snapshot_push_stroke (snapshot, self->text_path, stroke);
|
||||
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 0.2 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
gsk_stroke_free (stroke);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
|
||||
if (self->editable && self->line_path)
|
||||
{
|
||||
GskPathBuilder *builder;
|
||||
|
||||
/* draw the control line */
|
||||
stroke = gsk_stroke_new (1.0);
|
||||
gtk_snapshot_push_stroke (snapshot, self->line_path, stroke);
|
||||
gsk_stroke_free (stroke);
|
||||
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
gtk_snapshot_pop (snapshot);
|
||||
|
||||
/* draw the points */
|
||||
builder = gsk_path_builder_new ();
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (self->points[i].x * width, self->points[i].y * height), POINT_SIZE);
|
||||
}
|
||||
path = gsk_path_builder_free_to_path (builder);
|
||||
|
||||
gtk_snapshot_push_fill (snapshot, path, GSK_FILL_RULE_WINDING);
|
||||
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 1, 1, 1, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
gtk_snapshot_pop (snapshot);
|
||||
|
||||
stroke = gsk_stroke_new (1.0);
|
||||
gtk_snapshot_push_stroke (snapshot, path, stroke);
|
||||
gsk_stroke_free (stroke);
|
||||
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
gtk_snapshot_pop (snapshot);
|
||||
|
||||
gsk_path_unref (path);
|
||||
}
|
||||
|
||||
if (self->line_closest >= 0)
|
||||
{
|
||||
GskPathBuilder *builder;
|
||||
GskPathPoint point;
|
||||
graphene_point_t closest;
|
||||
|
||||
builder = gsk_path_builder_new ();
|
||||
if (gsk_path_measure_get_point (self->line_measure, self->line_closest, &point))
|
||||
{
|
||||
gsk_path_point_get_position (self->line_path, &point, &closest);
|
||||
gsk_path_builder_add_circle (builder, &closest, POINT_SIZE);
|
||||
path = gsk_path_builder_free_to_path (builder);
|
||||
|
||||
gtk_snapshot_push_fill (snapshot, path, GSK_FILL_RULE_WINDING);
|
||||
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 1, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
gtk_snapshot_pop (snapshot);
|
||||
|
||||
gsk_path_unref (path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_set_text (GtkPathWidget *self,
|
||||
const char *text)
|
||||
{
|
||||
if (g_strcmp0 (self->text, text) == 0)
|
||||
return;
|
||||
|
||||
g_free (self->text);
|
||||
self->text = g_strdup (text);
|
||||
|
||||
gtk_path_widget_create_paths (self);
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TEXT]);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_set_editable (GtkPathWidget *self,
|
||||
gboolean editable)
|
||||
{
|
||||
if (self->editable == editable)
|
||||
return;
|
||||
|
||||
self->editable = editable;
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_EDITABLE]);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
|
||||
{
|
||||
GtkPathWidget *self = GTK_PATH_WIDGET (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TEXT:
|
||||
gtk_path_widget_set_text (self, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_EDITABLE:
|
||||
gtk_path_widget_set_editable (self, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkPathWidget *self = GTK_PATH_WIDGET (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TEXT:
|
||||
g_value_set_string (value, self->text);
|
||||
break;
|
||||
|
||||
case PROP_EDITABLE:
|
||||
g_value_set_boolean (value, self->editable);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_dispose (GObject *object)
|
||||
{
|
||||
GtkPathWidget *self = GTK_PATH_WIDGET (object);
|
||||
|
||||
gtk_path_widget_clear_paths (self);
|
||||
|
||||
G_OBJECT_CLASS (gtk_path_widget_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_class_init (GtkPathWidgetClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gtk_path_widget_dispose;
|
||||
object_class->set_property = gtk_path_widget_set_property;
|
||||
object_class->get_property = gtk_path_widget_get_property;
|
||||
|
||||
widget_class->size_allocate = gtk_path_widget_allocate;
|
||||
widget_class->snapshot = gtk_path_widget_snapshot;
|
||||
|
||||
properties[PROP_TEXT] =
|
||||
g_param_spec_string ("text",
|
||||
"text",
|
||||
"Text transformed along a path",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_EDITABLE] =
|
||||
g_param_spec_boolean ("editable",
|
||||
"editable",
|
||||
"If the path can be edited by the user",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
}
|
||||
|
||||
static void
|
||||
drag_begin (GtkGestureDrag *gesture,
|
||||
double x,
|
||||
double y,
|
||||
GtkPathWidget *self)
|
||||
{
|
||||
graphene_point_t mouse = GRAPHENE_POINT_INIT (x, y);
|
||||
double width = gtk_widget_get_width (GTK_WIDGET (self));
|
||||
double height = gtk_widget_get_height (GTK_WIDGET (self));
|
||||
gsize i;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (graphene_point_distance (&GRAPHENE_POINT_INIT (self->points[i].x * width, self->points[i].y * height), &mouse, NULL, NULL) <= POINT_SIZE)
|
||||
{
|
||||
self->active_point = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == 4)
|
||||
{
|
||||
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
drag_update (GtkGestureDrag *drag,
|
||||
double offset_x,
|
||||
double offset_y,
|
||||
GtkPathWidget *self)
|
||||
{
|
||||
double width = gtk_widget_get_width (GTK_WIDGET (self));
|
||||
double height = gtk_widget_get_height (GTK_WIDGET (self));
|
||||
double start_x, start_y;
|
||||
|
||||
gtk_gesture_drag_get_start_point (drag, &start_x, &start_y);
|
||||
|
||||
self->points[self->active_point] = GRAPHENE_POINT_INIT ((start_x + offset_x) / width,
|
||||
(start_y + offset_y) / height);
|
||||
self->points[self->active_point].x = CLAMP (self->points[self->active_point].x, 0, 1);
|
||||
self->points[self->active_point].y = CLAMP (self->points[self->active_point].y, 0, 1);
|
||||
|
||||
gtk_path_widget_create_paths (self);
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_motion (GtkEventControllerMotion *controller,
|
||||
double x,
|
||||
double y,
|
||||
GtkPathWidget *self)
|
||||
{
|
||||
GskPathPoint point;
|
||||
graphene_point_t pos;
|
||||
|
||||
if (gsk_path_get_closest_point (gsk_path_measure_get_path (self->line_measure),
|
||||
&GRAPHENE_POINT_INIT (x, y),
|
||||
INFINITY,
|
||||
&point))
|
||||
{
|
||||
gsk_path_point_get_position (self->line_path, &point, &pos);
|
||||
self->line_closest = graphene_point_distance (&pos, &GRAPHENE_POINT_INIT (x, y), NULL, NULL);
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_leave (GtkEventControllerMotion *controller,
|
||||
GtkPathWidget *self)
|
||||
{
|
||||
self->line_closest = -1;
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_init (GtkPathWidget *self)
|
||||
{
|
||||
GtkEventController *controller;
|
||||
|
||||
controller = GTK_EVENT_CONTROLLER (gtk_gesture_drag_new ());
|
||||
g_signal_connect (controller, "drag-begin", G_CALLBACK (drag_begin), self);
|
||||
g_signal_connect (controller, "drag-update", G_CALLBACK (drag_update), self);
|
||||
g_signal_connect (controller, "drag-end", G_CALLBACK (drag_update), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), controller);
|
||||
|
||||
controller = GTK_EVENT_CONTROLLER (gtk_event_controller_motion_new ());
|
||||
g_signal_connect (controller, "enter", G_CALLBACK (pointer_motion), self);
|
||||
g_signal_connect (controller, "motion", G_CALLBACK (pointer_motion), self);
|
||||
g_signal_connect (controller, "leave", G_CALLBACK (pointer_leave), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), controller);
|
||||
|
||||
self->line_closest = -1;
|
||||
|
||||
self->points[0] = GRAPHENE_POINT_INIT (0.1, 0.9);
|
||||
self->points[1] = GRAPHENE_POINT_INIT (0.3, 0.1);
|
||||
self->points[2] = GRAPHENE_POINT_INIT (0.7, 0.1);
|
||||
self->points[3] = GRAPHENE_POINT_INIT (0.9, 0.9);
|
||||
|
||||
self->background = GDK_PAINTABLE (gdk_texture_new_from_resource ("/sliding_puzzle/portland-rose.jpg"));
|
||||
|
||||
gtk_path_widget_set_text (self, "It's almost working");
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
gtk_path_widget_new (void)
|
||||
{
|
||||
GtkPathWidget *self;
|
||||
|
||||
self = g_object_new (GTK_TYPE_PATH_WIDGET, NULL);
|
||||
|
||||
return GTK_WIDGET (self);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_path_text (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
|
||||
g_type_ensure (GTK_TYPE_PATH_WIDGET);
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/path_text/path_text.ui");
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
|
||||
return window;
|
||||
}
|
||||
38
demos/gtk-demo/path_text.ui
Normal file
38
demos/gtk-demo/path_text.ui
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkWindow" id="window">
|
||||
<property name="title" translatable="yes">Text along a Path</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<child type="end">
|
||||
<object class="GtkToggleButton" id="edit-toggle">
|
||||
<property name="icon-name">document-edit-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkRevealer">
|
||||
<property name="reveal-child" bind-source="edit-toggle" bind-property="active" bind-flags="sync-create"></property>
|
||||
<child>
|
||||
<object class="GtkEntry" id="text">
|
||||
<property name="text">Through the looking glass</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkPathWidget" id="view">
|
||||
<property name="editable" bind-source="edit-toggle" bind-property="active" bind-flags="sync-create"></property>
|
||||
<property name="text" bind-source="text" bind-property="text" bind-flags="sync-create"></property>
|
||||
<property name="hexpand">true</property>
|
||||
<property name="vexpand">true</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
@@ -6,6 +6,6 @@
|
||||
* Also, when adding new style properties, please add them here.
|
||||
*/
|
||||
|
||||
* {
|
||||
window.demo * {
|
||||
all: unset;
|
||||
}
|
||||
|
||||
@@ -188,10 +188,20 @@ do_spinbutton (GtkWidget *do_widget)
|
||||
if (!window)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
GtkBuilderScope *scope;
|
||||
GtkAdjustment *adj;
|
||||
GtkWidget *label;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/spinbutton/spinbutton.ui");
|
||||
scope = gtk_builder_cscope_new ();
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_cscope_add_callback (GTK_BUILDER_CSCOPE (scope), spinbutton_hex_spin_input);
|
||||
gtk_builder_cscope_add_callback (GTK_BUILDER_CSCOPE (scope), spinbutton_hex_spin_output);
|
||||
gtk_builder_cscope_add_callback (GTK_BUILDER_CSCOPE (scope), spinbutton_time_spin_input);
|
||||
gtk_builder_cscope_add_callback (GTK_BUILDER_CSCOPE (scope), spinbutton_time_spin_output);
|
||||
gtk_builder_cscope_add_callback (GTK_BUILDER_CSCOPE (scope), spinbutton_month_spin_input);
|
||||
gtk_builder_cscope_add_callback (GTK_BUILDER_CSCOPE (scope), spinbutton_month_spin_output);
|
||||
gtk_builder_set_scope (builder, scope);
|
||||
gtk_builder_add_from_resource (builder, "/spinbutton/spinbutton.ui", NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
@@ -233,6 +243,7 @@ do_spinbutton (GtkWidget *do_widget)
|
||||
NULL, NULL);
|
||||
|
||||
g_object_unref (builder);
|
||||
g_object_unref (scope);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -27,7 +27,6 @@ GtkWidget *
|
||||
do_spinner (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
GtkWidget *content_area;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *hbox;
|
||||
GtkWidget *button;
|
||||
@@ -35,28 +34,19 @@ do_spinner (GtkWidget *do_widget)
|
||||
|
||||
if (!window)
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
window = gtk_dialog_new_with_buttons ("Spinner",
|
||||
GTK_WINDOW (do_widget),
|
||||
0,
|
||||
_("_Close"),
|
||||
GTK_RESPONSE_NONE,
|
||||
NULL);
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Spinner");
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
|
||||
g_signal_connect (window, "response",
|
||||
G_CALLBACK (gtk_window_destroy), NULL);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
||||
gtk_widget_set_margin_start (vbox, 5);
|
||||
gtk_widget_set_margin_end (vbox, 5);
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
|
||||
gtk_widget_set_margin_top (vbox, 5);
|
||||
gtk_widget_set_margin_bottom (vbox, 5);
|
||||
gtk_box_append (GTK_BOX (content_area), vbox);
|
||||
gtk_widget_set_margin_start (vbox, 5);
|
||||
gtk_widget_set_margin_end (vbox, 5);
|
||||
|
||||
gtk_window_set_child (GTK_WINDOW (window), vbox);
|
||||
|
||||
/* Sensitive */
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
|
||||
|
||||
@@ -801,7 +801,7 @@ suggestion_entry_key_pressed (GtkEventControllerKey *controller,
|
||||
selected = matches - 1;
|
||||
}
|
||||
|
||||
gtk_single_selection_set_selected (self->selection, selected);
|
||||
gtk_list_view_scroll_to (GTK_LIST_VIEW (self->list), selected, GTK_LIST_SCROLL_SELECT, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
|
||||
#include "demo_conf.h"
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static GtkWidget *main_window;
|
||||
static GFile *filename = NULL;
|
||||
static GtkPageSetup *page_setup = NULL;
|
||||
@@ -43,7 +41,7 @@ update_statusbar (void)
|
||||
GtkTextIter iter;
|
||||
const char *print_str;
|
||||
|
||||
gtk_statusbar_pop (GTK_STATUSBAR (statusbar), 0);
|
||||
gtk_label_set_label (GTK_LABEL (statusbar), "");
|
||||
|
||||
gtk_text_buffer_get_iter_at_mark (buffer,
|
||||
&iter,
|
||||
@@ -61,10 +59,10 @@ update_statusbar (void)
|
||||
|
||||
msg = g_strdup_printf ("%d, %d%s %s",
|
||||
row, col,
|
||||
file_changed?" - Modified":"",
|
||||
print_str);
|
||||
file_changed?" - Modified":"",
|
||||
print_str);
|
||||
|
||||
gtk_statusbar_push (GTK_STATUSBAR (statusbar), 0, msg);
|
||||
gtk_label_set_label (GTK_LABEL (statusbar), msg);
|
||||
|
||||
g_free (msg);
|
||||
}
|
||||
@@ -827,7 +825,12 @@ activate (GApplication *app)
|
||||
contents);
|
||||
|
||||
/* Create statusbar */
|
||||
statusbar = gtk_statusbar_new ();
|
||||
statusbar = gtk_label_new ("");
|
||||
gtk_label_set_xalign (GTK_LABEL (statusbar), 0);
|
||||
gtk_widget_set_margin_start (statusbar, 2);
|
||||
gtk_widget_set_margin_end (statusbar, 2);
|
||||
gtk_widget_set_margin_top (statusbar, 2);
|
||||
gtk_widget_set_margin_bottom (statusbar, 2);
|
||||
gtk_box_append (GTK_BOX (box), statusbar);
|
||||
|
||||
/* Show text widget info in the statusbar */
|
||||
|
||||
@@ -5,16 +5,6 @@ How to do a GTK release?
|
||||
|
||||
Make sure you have suitable versions of Meson and Ninja.
|
||||
|
||||
Also make sure you have the following packages installed with all their
|
||||
dependencies:
|
||||
|
||||
* gtk-doc
|
||||
* docbook-utils
|
||||
|
||||
Without those packages make distcheck will *not* pass.
|
||||
|
||||
Make sure that gtk-doc is the latest released version.
|
||||
|
||||
## Release check list
|
||||
|
||||
0. Save all your work, then move to the branch from which you want
|
||||
@@ -28,8 +18,8 @@ $ git clean -dfx
|
||||
1. Build using the common sequence:
|
||||
|
||||
```sh
|
||||
$ meson _build .
|
||||
$ ninja -C _build
|
||||
$ meson setup _build
|
||||
$ meson compile -C _build
|
||||
```
|
||||
|
||||
2. Update NEWS based on the content of git log; follow the format of prior
|
||||
@@ -40,11 +30,10 @@ $ ninja -C _build
|
||||
writers, committers, etc. Anybody who is mentioned in the commit log
|
||||
gets a credit, but only real names, not email addresses or nicknames.
|
||||
|
||||
3. Update the pot files and commit the changes:
|
||||
3. Update the pot file and commit the changes:
|
||||
|
||||
```sh
|
||||
$ ninja -C _build gtk40-pot
|
||||
$ ninja -C _build gtk40-properties-pot
|
||||
```
|
||||
|
||||
4. If this is a major, stable, release, verify that the release notes
|
||||
@@ -72,7 +61,7 @@ $ ninja -C _build gtk40-properties-pot
|
||||
Make sure that all new symbols have proper Since: tags, and that there
|
||||
is an index in the main `-docs.xml` for the next stable version.
|
||||
|
||||
8. Run `ninja dist` to generate the tarball.
|
||||
8. Run `meson dist -C_build` to generate the tarball.
|
||||
|
||||
9. Fix broken stuff found by 8), commit changes, repeat.
|
||||
|
||||
@@ -94,7 +83,8 @@ $ ninja -C _build gtk40-properties-pot
|
||||
$ git tag -m "GTK 4.2.0" 4.2.0
|
||||
```
|
||||
|
||||
13. Bump the version number in `meson.build` and commit the change.
|
||||
13. Bump the version number in `meson.build`, and add a section for the next
|
||||
release in NEWS and commit the change.
|
||||
|
||||
14. Push the changes upstream, and push the tag as well. The git command for
|
||||
doing that is:
|
||||
@@ -111,7 +101,8 @@ $ git push origin 4.2.0
|
||||
|
||||
```sh
|
||||
$ scp gtk-4.2.0.tar.xz matthiasc@master.gnome.org:
|
||||
$ ssh matthiasc@master.gnome.org ftpadmin install gtk-4.2.0.tar.xz
|
||||
$ ssh matthiasc@master.gnome.org
|
||||
$ ftpadmin install gtk-4.2.0.tar.xz
|
||||
```
|
||||
|
||||
16. Go to the gnome-announce list archives, find the last announce message,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
expand_content_md_files = [
|
||||
]
|
||||
|
||||
if get_option('gtk_doc')
|
||||
if get_option('documentation')
|
||||
gdk4_toml = configure_file(
|
||||
input: 'gdk4.toml.in',
|
||||
output: 'gdk4.toml',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
if get_option('gtk_doc')
|
||||
if get_option('documentation')
|
||||
gsk4_toml = configure_file(
|
||||
input: 'gsk4.toml.in',
|
||||
output: 'gsk4.toml',
|
||||
|
||||
@@ -268,7 +268,7 @@ support in the file chooser.
|
||||
This option controls whether GTK should use colord for color
|
||||
calibration support in the cups print backend.
|
||||
|
||||
### `gtk_doc`, `man-pages` and `update_screenshots`
|
||||
### `documentation`, `man-pages` and `screenshots`
|
||||
|
||||
The *gi-docgen* package is used to generate the reference documentation
|
||||
included with GTK. By default support for *gi-docgen* is disabled
|
||||
|
||||
@@ -89,11 +89,11 @@ using `gtk_application_new()`.
|
||||
When creating a [class@Gtk.Application], you need to pick an application
|
||||
identifier (a name) and pass it to [ctor@Gtk.Application.new] as parameter. For
|
||||
this example `org.gtk.example` is used. For choosing an identifier for your
|
||||
application, see [this guide](https://wiki.gnome.org/HowDoI/ChooseApplicationID).
|
||||
application, see [this guide](https://developer.gnome.org/documentation/tutorials/application-id.html).
|
||||
Lastly, [ctor@Gtk.Application.new] takes `GApplicationFlags` as input
|
||||
for your application, if your application would have special needs.
|
||||
|
||||
Next the [activate signal](https://wiki.gnome.org/HowDoI/GtkApplication) is
|
||||
Next the [activate signal](https://developer.gnome.org/documentation/tutorials/application.html) is
|
||||
connected to the activate() function above the `main()` function. The `activate`
|
||||
signal will be emitted when your application is launched with `g_application_run()`
|
||||
on the line below. The `g_application_run()` call also takes as arguments the
|
||||
|
||||
47
docs/reference/gtk/gtk4-rendernode-tool.rst
Normal file
47
docs/reference/gtk/gtk4-rendernode-tool.rst
Normal file
@@ -0,0 +1,47 @@
|
||||
.. _gtk4-rendernode-tool(1):
|
||||
|
||||
====================
|
||||
gtk4-rendernode-tool
|
||||
====================
|
||||
|
||||
-----------------------
|
||||
GskRenderNode Utility
|
||||
-----------------------
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
| **gtk4-rendernode-tool** <COMMAND> [OPTIONS...] <FILE>
|
||||
|
|
||||
| **gtk4-rendernode-tool** info [OPTIONS...] <FILE>
|
||||
| **gtk4-rendernode-tool** show [OPTIONS...] <FILE>
|
||||
| **gtk4-rendernode-tool** render [OPTIONS...] <FILE> [<FILE>]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
||||
``gtk4-rendernode-tool`` can perform various operations on serialized rendernodes.
|
||||
|
||||
COMMANDS
|
||||
--------
|
||||
|
||||
Information
|
||||
^^^^^^^^^^^
|
||||
|
||||
The ``info`` command shows general information about the rendernode, such
|
||||
as the number of nodes, and the depth of the tree.
|
||||
|
||||
Showing
|
||||
^^^^^^^
|
||||
|
||||
The ``show`` command displays the rendernode.
|
||||
|
||||
Rendering
|
||||
^^^^^^^^^
|
||||
|
||||
The ``render`` command saves a rendering of the rendernode as a png or tiff image.
|
||||
The name of the file to write can be specified as a second FILE argument.
|
||||
|
||||
``--renderer=RENDERER``
|
||||
|
||||
Use the given renderer. Use ``--renderer=help`` to get a information
|
||||
about poassible values for the ``RENDERER``.
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 147 B After Width: | Height: | Size: 7.0 KiB |
@@ -78,7 +78,7 @@ ui_files = [
|
||||
|
||||
gtk_builder_tool = find_program('gtk4-builder-tool')
|
||||
|
||||
if get_option('update_screenshots')
|
||||
if get_option('screenshots')
|
||||
foreach ui_file: ui_files
|
||||
png_file = ui_file.replace('.ui', '.png')
|
||||
gtk_images += custom_target('@0@ from @1@'.format(png_file, ui_file),
|
||||
|
||||
@@ -32,7 +32,7 @@ gtk_images = []
|
||||
|
||||
subdir('images')
|
||||
|
||||
if get_option('gtk_doc')
|
||||
if get_option('documentation')
|
||||
gtk4_toml = configure_file(
|
||||
input: 'gtk4.toml.in',
|
||||
output: 'gtk4.toml',
|
||||
@@ -75,6 +75,7 @@ if get_option('man-pages') and rst2man.found()
|
||||
[ 'gtk4-encode-symbolic-svg', '1', ],
|
||||
[ 'gtk4-launch', '1', ],
|
||||
[ 'gtk4-query-settings', '1', ],
|
||||
[ 'gtk4-rendernode-tool', '1' ],
|
||||
[ 'gtk4-update-icon-cache', '1', ],
|
||||
]
|
||||
|
||||
|
||||
@@ -73,9 +73,6 @@ A number of keys are influencing behavior instead of just logging:
|
||||
`no-css-cache`
|
||||
: Bypass caching for CSS style properties
|
||||
|
||||
`touchscreen`
|
||||
: Pretend the pointer is a touchscreen device
|
||||
|
||||
`snapshot`
|
||||
: Include debug render nodes in the generated snapshots
|
||||
|
||||
|
||||
@@ -222,7 +222,7 @@ It is possible to set accessible attributes in UI files as well:
|
||||
<accessibility>
|
||||
<property name="label">Download</property>
|
||||
<relation name="labelled-by">label1</relation>
|
||||
/accessibility>
|
||||
</accessibility>
|
||||
</object>
|
||||
```
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
toml_conf = configuration_data()
|
||||
toml_conf.set('version', meson.project_version())
|
||||
|
||||
gidocgen = find_program('gi-docgen', required: get_option('gtk_doc'), native: true)
|
||||
gidocgen = find_program('gi-docgen', required: get_option('documentation'), native: true)
|
||||
|
||||
gidocgen_common_args = [
|
||||
'--quiet',
|
||||
@@ -14,7 +14,7 @@ endif
|
||||
|
||||
docs_dir = gtk_datadir / 'doc'
|
||||
|
||||
if get_option('gtk_doc') and not build_gir
|
||||
if get_option('documentation') and not build_gir
|
||||
error('API reference requires introspection.')
|
||||
endif
|
||||
|
||||
|
||||
@@ -15,18 +15,78 @@ struct _ExampleAppPrefs
|
||||
|
||||
G_DEFINE_TYPE (ExampleAppPrefs, example_app_prefs, GTK_TYPE_DIALOG)
|
||||
|
||||
static gboolean
|
||||
string_to_font_desc (GValue *value,
|
||||
GVariant *variant,
|
||||
gpointer user_data)
|
||||
{
|
||||
const char *s = g_variant_get_string (variant, NULL);
|
||||
PangoFontDescription *desc;
|
||||
|
||||
desc = pango_font_description_from_string (s);
|
||||
g_value_take_boxed (value, desc);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
font_desc_to_string (const GValue *value,
|
||||
const GVariantType *expected_type,
|
||||
gpointer user_data)
|
||||
{
|
||||
PangoFontDescription *desc = g_value_get_boxed (value);
|
||||
char *s = pango_font_description_to_string (desc);
|
||||
return g_variant_new_take_string (s);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
transition_to_pos (GValue *value,
|
||||
GVariant *variant,
|
||||
gpointer user_data)
|
||||
{
|
||||
const char *s = g_variant_get_string (variant, NULL);
|
||||
if (strcmp (s, "none") == 0)
|
||||
g_value_set_uint (value, 0);
|
||||
else if (strcmp (s, "crossfade") == 0)
|
||||
g_value_set_uint (value, 1);
|
||||
else
|
||||
g_value_set_uint (value, 2);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
pos_to_transition (const GValue *value,
|
||||
const GVariantType *expected_type,
|
||||
gpointer user_data)
|
||||
{
|
||||
switch (g_value_get_uint (value))
|
||||
{
|
||||
case 0: return g_variant_new_string ("none");
|
||||
case 1: return g_variant_new_string ("crossfade");
|
||||
case 2: return g_variant_new_string ("slide-left-right");
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
example_app_prefs_init (ExampleAppPrefs *prefs)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (prefs));
|
||||
prefs->settings = g_settings_new ("org.gtk.exampleapp");
|
||||
|
||||
g_settings_bind (prefs->settings, "font",
|
||||
prefs->font, "font",
|
||||
G_SETTINGS_BIND_DEFAULT);
|
||||
g_settings_bind (prefs->settings, "transition",
|
||||
prefs->transition, "active-id",
|
||||
G_SETTINGS_BIND_DEFAULT);
|
||||
g_settings_bind_with_mapping (prefs->settings, "font",
|
||||
prefs->font, "font-desc",
|
||||
G_SETTINGS_BIND_DEFAULT,
|
||||
string_to_font_desc,
|
||||
font_desc_to_string,
|
||||
NULL, NULL);
|
||||
g_settings_bind_with_mapping (prefs->settings, "transition",
|
||||
prefs->transition, "selected",
|
||||
G_SETTINGS_BIND_DEFAULT,
|
||||
transition_to_pos,
|
||||
pos_to_transition,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -27,7 +27,10 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFontButton" id="font">
|
||||
<object class="GtkFontDialogButton" id="font">
|
||||
<property name="dialog">
|
||||
<object class="GtkFontDialog"/>
|
||||
</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">0</property>
|
||||
@@ -47,12 +50,16 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="transition">
|
||||
<items>
|
||||
<item translatable="yes" id="none">None</item>
|
||||
<item translatable="yes" id="crossfade">Fade</item>
|
||||
<item translatable="yes" id="slide-left-right">Slide</item>
|
||||
</items>
|
||||
<object class="GtkDropDown" id="transition">
|
||||
<property name="model">
|
||||
<object class="GtkStringList">
|
||||
<items>
|
||||
<item translatable="yes">None</item>
|
||||
<item translatable="yes">Fade</item>
|
||||
<item translatable="yes">Slide</item>
|
||||
</items>
|
||||
</object>
|
||||
</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">1</property>
|
||||
|
||||
@@ -15,18 +15,78 @@ struct _ExampleAppPrefs
|
||||
|
||||
G_DEFINE_TYPE (ExampleAppPrefs, example_app_prefs, GTK_TYPE_DIALOG)
|
||||
|
||||
static gboolean
|
||||
string_to_font_desc (GValue *value,
|
||||
GVariant *variant,
|
||||
gpointer user_data)
|
||||
{
|
||||
const char *s = g_variant_get_string (variant, NULL);
|
||||
PangoFontDescription *desc;
|
||||
|
||||
desc = pango_font_description_from_string (s);
|
||||
g_value_take_boxed (value, desc);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
font_desc_to_string (const GValue *value,
|
||||
const GVariantType *expected_type,
|
||||
gpointer user_data)
|
||||
{
|
||||
PangoFontDescription *desc = g_value_get_boxed (value);
|
||||
char *s = pango_font_description_to_string (desc);
|
||||
return g_variant_new_take_string (s);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
transition_to_pos (GValue *value,
|
||||
GVariant *variant,
|
||||
gpointer user_data)
|
||||
{
|
||||
const char *s = g_variant_get_string (variant, NULL);
|
||||
if (strcmp (s, "none") == 0)
|
||||
g_value_set_uint (value, 0);
|
||||
else if (strcmp (s, "crossfade") == 0)
|
||||
g_value_set_uint (value, 1);
|
||||
else
|
||||
g_value_set_uint (value, 2);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
pos_to_transition (const GValue *value,
|
||||
const GVariantType *expected_type,
|
||||
gpointer user_data)
|
||||
{
|
||||
switch (g_value_get_uint (value))
|
||||
{
|
||||
case 0: return g_variant_new_string ("none");
|
||||
case 1: return g_variant_new_string ("crossfade");
|
||||
case 2: return g_variant_new_string ("slide-left-right");
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
example_app_prefs_init (ExampleAppPrefs *prefs)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (prefs));
|
||||
prefs->settings = g_settings_new ("org.gtk.exampleapp");
|
||||
|
||||
g_settings_bind (prefs->settings, "font",
|
||||
prefs->font, "font",
|
||||
G_SETTINGS_BIND_DEFAULT);
|
||||
g_settings_bind (prefs->settings, "transition",
|
||||
prefs->transition, "active-id",
|
||||
G_SETTINGS_BIND_DEFAULT);
|
||||
g_settings_bind_with_mapping (prefs->settings, "font",
|
||||
prefs->font, "font-desc",
|
||||
G_SETTINGS_BIND_DEFAULT,
|
||||
string_to_font_desc,
|
||||
font_desc_to_string,
|
||||
NULL, NULL);
|
||||
g_settings_bind_with_mapping (prefs->settings, "transition",
|
||||
prefs->transition, "selected",
|
||||
G_SETTINGS_BIND_DEFAULT,
|
||||
transition_to_pos,
|
||||
pos_to_transition,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -27,7 +27,10 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFontButton" id="font">
|
||||
<object class="GtkFontDialogButton" id="font">
|
||||
<property name="dialog">
|
||||
<object class="GtkFontDialog"/>
|
||||
</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">0</property>
|
||||
@@ -47,12 +50,16 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="transition">
|
||||
<items>
|
||||
<item translatable="yes" id="none">None</item>
|
||||
<item translatable="yes" id="crossfade">Fade</item>
|
||||
<item translatable="yes" id="slide-left-right">Slide</item>
|
||||
</items>
|
||||
<object class="GtkDropDown" id="transition">
|
||||
<property name="model">
|
||||
<object class="GtkStringList">
|
||||
<items>
|
||||
<item translatable="yes">None</item>
|
||||
<item translatable="yes">Fade</item>
|
||||
<item translatable="yes">Slide</item>
|
||||
</items>
|
||||
</object>
|
||||
</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">1</property>
|
||||
|
||||
@@ -15,18 +15,78 @@ struct _ExampleAppPrefs
|
||||
|
||||
G_DEFINE_TYPE (ExampleAppPrefs, example_app_prefs, GTK_TYPE_DIALOG)
|
||||
|
||||
static gboolean
|
||||
string_to_font_desc (GValue *value,
|
||||
GVariant *variant,
|
||||
gpointer user_data)
|
||||
{
|
||||
const char *s = g_variant_get_string (variant, NULL);
|
||||
PangoFontDescription *desc;
|
||||
|
||||
desc = pango_font_description_from_string (s);
|
||||
g_value_take_boxed (value, desc);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
font_desc_to_string (const GValue *value,
|
||||
const GVariantType *expected_type,
|
||||
gpointer user_data)
|
||||
{
|
||||
PangoFontDescription *desc = g_value_get_boxed (value);
|
||||
char *s = pango_font_description_to_string (desc);
|
||||
return g_variant_new_take_string (s);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
transition_to_pos (GValue *value,
|
||||
GVariant *variant,
|
||||
gpointer user_data)
|
||||
{
|
||||
const char *s = g_variant_get_string (variant, NULL);
|
||||
if (strcmp (s, "none") == 0)
|
||||
g_value_set_uint (value, 0);
|
||||
else if (strcmp (s, "crossfade") == 0)
|
||||
g_value_set_uint (value, 1);
|
||||
else
|
||||
g_value_set_uint (value, 2);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
pos_to_transition (const GValue *value,
|
||||
const GVariantType *expected_type,
|
||||
gpointer user_data)
|
||||
{
|
||||
switch (g_value_get_uint (value))
|
||||
{
|
||||
case 0: return g_variant_new_string ("none");
|
||||
case 1: return g_variant_new_string ("crossfade");
|
||||
case 2: return g_variant_new_string ("slide-left-right");
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
example_app_prefs_init (ExampleAppPrefs *prefs)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (prefs));
|
||||
prefs->settings = g_settings_new ("org.gtk.exampleapp");
|
||||
|
||||
g_settings_bind (prefs->settings, "font",
|
||||
prefs->font, "font",
|
||||
G_SETTINGS_BIND_DEFAULT);
|
||||
g_settings_bind (prefs->settings, "transition",
|
||||
prefs->transition, "active-id",
|
||||
G_SETTINGS_BIND_DEFAULT);
|
||||
g_settings_bind_with_mapping (prefs->settings, "font",
|
||||
prefs->font, "font-desc",
|
||||
G_SETTINGS_BIND_DEFAULT,
|
||||
string_to_font_desc,
|
||||
font_desc_to_string,
|
||||
NULL, NULL);
|
||||
g_settings_bind_with_mapping (prefs->settings, "transition",
|
||||
prefs->transition, "selected",
|
||||
G_SETTINGS_BIND_DEFAULT,
|
||||
transition_to_pos,
|
||||
pos_to_transition,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -27,7 +27,10 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFontButton" id="font">
|
||||
<object class="GtkFontDialogButton" id="font">
|
||||
<property name="dialog">
|
||||
<object class="GtkFontDialog"/>
|
||||
</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">0</property>
|
||||
@@ -47,12 +50,16 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="transition">
|
||||
<items>
|
||||
<item translatable="yes" id="none">None</item>
|
||||
<item translatable="yes" id="crossfade">Fade</item>
|
||||
<item translatable="yes" id="slide-left-right">Slide</item>
|
||||
</items>
|
||||
<object class="GtkDropDown" id="transition">
|
||||
<property name="model">
|
||||
<object class="GtkStringList">
|
||||
<items>
|
||||
<item translatable="yes">None</item>
|
||||
<item translatable="yes">Fade</item>
|
||||
<item translatable="yes">Slide</item>
|
||||
</items>
|
||||
</object>
|
||||
</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">1</property>
|
||||
|
||||
@@ -15,18 +15,78 @@ struct _ExampleAppPrefs
|
||||
|
||||
G_DEFINE_TYPE (ExampleAppPrefs, example_app_prefs, GTK_TYPE_DIALOG)
|
||||
|
||||
static gboolean
|
||||
string_to_font_desc (GValue *value,
|
||||
GVariant *variant,
|
||||
gpointer user_data)
|
||||
{
|
||||
const char *s = g_variant_get_string (variant, NULL);
|
||||
PangoFontDescription *desc;
|
||||
|
||||
desc = pango_font_description_from_string (s);
|
||||
g_value_take_boxed (value, desc);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
font_desc_to_string (const GValue *value,
|
||||
const GVariantType *expected_type,
|
||||
gpointer user_data)
|
||||
{
|
||||
PangoFontDescription *desc = g_value_get_boxed (value);
|
||||
char *s = pango_font_description_to_string (desc);
|
||||
return g_variant_new_take_string (s);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
transition_to_pos (GValue *value,
|
||||
GVariant *variant,
|
||||
gpointer user_data)
|
||||
{
|
||||
const char *s = g_variant_get_string (variant, NULL);
|
||||
if (strcmp (s, "none") == 0)
|
||||
g_value_set_uint (value, 0);
|
||||
else if (strcmp (s, "crossfade") == 0)
|
||||
g_value_set_uint (value, 1);
|
||||
else
|
||||
g_value_set_uint (value, 2);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
pos_to_transition (const GValue *value,
|
||||
const GVariantType *expected_type,
|
||||
gpointer user_data)
|
||||
{
|
||||
switch (g_value_get_uint (value))
|
||||
{
|
||||
case 0: return g_variant_new_string ("none");
|
||||
case 1: return g_variant_new_string ("crossfade");
|
||||
case 2: return g_variant_new_string ("slide-left-right");
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
example_app_prefs_init (ExampleAppPrefs *prefs)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (prefs));
|
||||
prefs->settings = g_settings_new ("org.gtk.exampleapp");
|
||||
|
||||
g_settings_bind (prefs->settings, "font",
|
||||
prefs->font, "font",
|
||||
G_SETTINGS_BIND_DEFAULT);
|
||||
g_settings_bind (prefs->settings, "transition",
|
||||
prefs->transition, "active-id",
|
||||
G_SETTINGS_BIND_DEFAULT);
|
||||
g_settings_bind_with_mapping (prefs->settings, "font",
|
||||
prefs->font, "font-desc",
|
||||
G_SETTINGS_BIND_DEFAULT,
|
||||
string_to_font_desc,
|
||||
font_desc_to_string,
|
||||
NULL, NULL);
|
||||
g_settings_bind_with_mapping (prefs->settings, "transition",
|
||||
prefs->transition, "selected",
|
||||
G_SETTINGS_BIND_DEFAULT,
|
||||
transition_to_pos,
|
||||
pos_to_transition,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -27,7 +27,10 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFontButton" id="font">
|
||||
<object class="GtkFontDialogButton" id="font">
|
||||
<property name="dialog">
|
||||
<object class="GtkFontDialog"/>
|
||||
</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">0</property>
|
||||
@@ -47,12 +50,16 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="transition">
|
||||
<items>
|
||||
<item translatable="yes" id="none">None</item>
|
||||
<item translatable="yes" id="crossfade">Fade</item>
|
||||
<item translatable="yes" id="slide-left-right">Slide</item>
|
||||
</items>
|
||||
<object class="GtkDropDown" id="transition">
|
||||
<property name="model">
|
||||
<object class="GtkStringList">
|
||||
<items>
|
||||
<item translatable="yes">None</item>
|
||||
<item translatable="yes">Fade</item>
|
||||
<item translatable="yes">Slide</item>
|
||||
</items>
|
||||
</object>
|
||||
</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">1</property>
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkApplication parent_instance;
|
||||
@@ -356,8 +354,8 @@ combo_changed (GtkDropDown *combo,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkDialog *dialog = user_data;
|
||||
GtkEntry *entry = g_object_get_data (user_data, "entry");
|
||||
GtkWidget *set_button = g_object_get_data (user_data, "set-button");
|
||||
const char *action;
|
||||
char **accels;
|
||||
char *str;
|
||||
@@ -372,7 +370,7 @@ combo_changed (GtkDropDown *combo,
|
||||
g_strfreev (accels);
|
||||
|
||||
gtk_editable_set_text (GTK_EDITABLE (entry), str);
|
||||
gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_APPLY, FALSE);
|
||||
gtk_widget_set_sensitive (set_button, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -380,15 +378,21 @@ entry_changed (GtkEntry *entry,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkDialog *dialog = user_data;
|
||||
GtkWidget *set_button = g_object_get_data (user_data, "set-button");
|
||||
|
||||
gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_APPLY, TRUE);
|
||||
gtk_widget_set_sensitive (set_button, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
response (GtkDialog *dialog,
|
||||
guint response_id,
|
||||
gpointer user_data)
|
||||
close_clicked (GtkButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
gtk_window_destroy (GTK_WINDOW (user_data));
|
||||
}
|
||||
|
||||
static void
|
||||
set_clicked (GtkButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkEntry *entry = g_object_get_data (user_data, "entry");
|
||||
GtkDropDown *combo = g_object_get_data (user_data, "combo");
|
||||
@@ -396,12 +400,6 @@ response (GtkDialog *dialog,
|
||||
const char *str;
|
||||
char **accels;
|
||||
|
||||
if (response_id == GTK_RESPONSE_CANCEL)
|
||||
{
|
||||
gtk_window_destroy (GTK_WINDOW (dialog));
|
||||
return;
|
||||
}
|
||||
|
||||
action = gtk_string_object_get_string (GTK_STRING_OBJECT (gtk_drop_down_get_selected_item (combo)));
|
||||
|
||||
if (!action)
|
||||
@@ -413,7 +411,7 @@ response (GtkDialog *dialog,
|
||||
gtk_application_set_accels_for_action (gtk_window_get_application (user_data), action, (const char **) accels);
|
||||
g_strfreev (accels);
|
||||
|
||||
gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_APPLY, FALSE);
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (button), FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -424,32 +422,45 @@ edit_accels (GSimpleAction *action,
|
||||
GtkApplication *app = user_data;
|
||||
GtkWidget *combo;
|
||||
GtkWidget *entry;
|
||||
GtkWidget *header;
|
||||
GtkWidget *close_button;
|
||||
GtkWidget *set_button;
|
||||
GtkWidget *box;
|
||||
char **actions;
|
||||
GtkWidget *dialog;
|
||||
int i;
|
||||
GtkStringList *strings;
|
||||
|
||||
dialog = gtk_dialog_new_with_buttons ("Accelerators",
|
||||
NULL,
|
||||
GTK_DIALOG_USE_HEADER_BAR,
|
||||
"Close", GTK_RESPONSE_CANCEL,
|
||||
"Set", GTK_RESPONSE_APPLY,
|
||||
NULL);
|
||||
|
||||
dialog = gtk_window_new ();
|
||||
gtk_window_set_title (GTK_WINDOW (dialog), "Accelerators");
|
||||
gtk_window_set_application (GTK_WINDOW (dialog), app);
|
||||
actions = gtk_application_list_action_descriptions (app);
|
||||
|
||||
strings = gtk_string_list_new (NULL);
|
||||
combo = gtk_drop_down_new (G_LIST_MODEL (strings), NULL);
|
||||
g_object_set (gtk_dialog_get_content_area (GTK_DIALOG (dialog)),
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
|
||||
close_button = gtk_button_new_with_label ("Close");
|
||||
g_signal_connect (close_button, "clicked", G_CALLBACK (close_clicked), dialog);
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), close_button);
|
||||
set_button = gtk_button_new_with_label ("Set");
|
||||
g_signal_connect (set_button, "clicked", G_CALLBACK (set_clicked), dialog);
|
||||
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), set_button);
|
||||
|
||||
gtk_window_set_titlebar (GTK_WINDOW (dialog), header);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
|
||||
g_object_set (box,
|
||||
"margin-top", 10,
|
||||
"margin-bottom", 10,
|
||||
"margin-start", 10,
|
||||
"margin-end", 10,
|
||||
"spacing", 10,
|
||||
NULL);
|
||||
gtk_window_set_child (GTK_WINDOW (dialog), box);
|
||||
|
||||
strings = gtk_string_list_new (NULL);
|
||||
combo = gtk_drop_down_new (G_LIST_MODEL (strings), NULL);
|
||||
|
||||
gtk_box_append (GTK_BOX (box), combo);
|
||||
|
||||
gtk_box_append (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), combo);
|
||||
for (i = 0; actions[i]; i++)
|
||||
gtk_string_list_append (strings, actions[i]);
|
||||
g_signal_connect (combo, "notify::selected", G_CALLBACK (combo_changed), dialog);
|
||||
@@ -458,10 +469,10 @@ edit_accels (GSimpleAction *action,
|
||||
gtk_widget_set_hexpand (entry, TRUE);
|
||||
g_signal_connect (entry, "notify::text", G_CALLBACK (entry_changed), dialog);
|
||||
|
||||
gtk_box_append (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), entry);
|
||||
g_signal_connect (dialog, "response", G_CALLBACK (response), dialog);
|
||||
gtk_box_append (GTK_BOX (box), entry);
|
||||
g_object_set_data (G_OBJECT (dialog), "combo", combo);
|
||||
g_object_set_data (G_OBJECT (dialog), "entry", entry);
|
||||
g_object_set_data (G_OBJECT (dialog), "set-button", set_button);
|
||||
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (combo), 0);
|
||||
|
||||
|
||||
@@ -13,8 +13,6 @@ foreach ex : examples
|
||||
example_name = ex == 'builder' ? 'builder_example' : ex
|
||||
executable(example_name, '@0@.c'.format(ex),
|
||||
c_args: [
|
||||
'-DGDK_DISABLE_DEPRECATED',
|
||||
'-DGTK_DISABLE_DEPRECATED',
|
||||
'-DGTK_SRCDIR="@0@"'.format(meson.current_source_dir()),
|
||||
] + common_cflags,
|
||||
dependencies: libgtk_dep)
|
||||
|
||||
@@ -364,6 +364,8 @@ typedef enum {
|
||||
GDK_MEMORY_G16 GDK_AVAILABLE_ENUMERATOR_IN_4_12,
|
||||
GDK_MEMORY_A8 GDK_AVAILABLE_ENUMERATOR_IN_4_12,
|
||||
GDK_MEMORY_A16 GDK_AVAILABLE_ENUMERATOR_IN_4_12,
|
||||
GDK_MEMORY_A16_FLOAT GDK_AVAILABLE_ENUMERATOR_IN_4_12,
|
||||
GDK_MEMORY_A32_FLOAT GDK_AVAILABLE_ENUMERATOR_IN_4_12,
|
||||
|
||||
GDK_MEMORY_N_FORMATS
|
||||
} GdkMemoryFormat;
|
||||
|
||||
@@ -69,9 +69,9 @@ name ## _to_float (float *dest, \
|
||||
for (gsize i = 0; i < n; i++) \
|
||||
{ \
|
||||
T *src = (T *) (src_data + i * bpp); \
|
||||
if (G >= 0) dest[0] = (float) src[G] / scale; else dest[0] = 1.0; \
|
||||
dest[1] = dest[2] = dest[0]; \
|
||||
if (A >= 0) dest[3] = (float) src[A] / scale; else dest[3] = 1.0; \
|
||||
if (G >= 0) dest[0] = (float) src[G] / scale; else dest[0] = dest[3]; \
|
||||
dest[1] = dest[2] = dest[0]; \
|
||||
dest += 4; \
|
||||
} \
|
||||
} \
|
||||
@@ -156,6 +156,37 @@ r16g16b16a16_float_from_float (guchar *dest,
|
||||
float_to_half (src, (guint16 *) dest, 4 * n);
|
||||
}
|
||||
|
||||
static void
|
||||
a16_float_to_float (float *dest,
|
||||
const guchar *src_data,
|
||||
gsize n)
|
||||
{
|
||||
const guint16 *src = (const guint16 *) src_data;
|
||||
for (gsize i = 0; i < n; i++)
|
||||
{
|
||||
half_to_float (src, dest, 1);
|
||||
dest[1] = dest[0];
|
||||
dest[2] = dest[0];
|
||||
dest[3] = dest[0];
|
||||
src++;
|
||||
dest += 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
a16_float_from_float (guchar *dest_data,
|
||||
const float *src,
|
||||
gsize n)
|
||||
{
|
||||
guint16 *dest = (guint16 *) dest_data;
|
||||
for (gsize i = 0; i < n; i++)
|
||||
{
|
||||
float_to_half (&src[3], dest, 1);
|
||||
dest ++;
|
||||
src += 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
r32g32b32_float_to_float (float *dest,
|
||||
const guchar *src_data,
|
||||
@@ -205,6 +236,37 @@ r32g32b32a32_float_from_float (guchar *dest,
|
||||
memcpy (dest, src, sizeof (float) * n * 4);
|
||||
}
|
||||
|
||||
static void
|
||||
a32_float_to_float (float *dest,
|
||||
const guchar *src_data,
|
||||
gsize n)
|
||||
{
|
||||
const float *src = (const float *) src_data;
|
||||
for (gsize i = 0; i < n; i++)
|
||||
{
|
||||
dest[0] = src[0];
|
||||
dest[1] = src[0];
|
||||
dest[2] = src[0];
|
||||
dest[3] = src[0];
|
||||
src++;
|
||||
dest += 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
a32_float_from_float (guchar *dest_data,
|
||||
const float *src,
|
||||
gsize n)
|
||||
{
|
||||
float *dest = (float *) dest_data;
|
||||
for (gsize i = 0; i < n; i++)
|
||||
{
|
||||
dest[0] = src[3];
|
||||
dest ++;
|
||||
src += 4;
|
||||
}
|
||||
}
|
||||
|
||||
#define PREMULTIPLY_FUNC(name, R1, G1, B1, A1, R2, G2, B2, A2) \
|
||||
static void \
|
||||
name (guchar *dest, \
|
||||
@@ -284,7 +346,7 @@ struct _GdkMemoryFormatDescription
|
||||
# error "Define the right GL flags here"
|
||||
#endif
|
||||
|
||||
static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
[GDK_MEMORY_B8G8R8A8_PREMULTIPLIED] = {
|
||||
GDK_MEMORY_ALPHA_PREMULTIPLIED,
|
||||
4,
|
||||
@@ -526,27 +588,50 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
g16_from_float,
|
||||
},
|
||||
[GDK_MEMORY_A8] = {
|
||||
GDK_MEMORY_ALPHA_STRAIGHT,
|
||||
GDK_MEMORY_ALPHA_PREMULTIPLIED,
|
||||
1,
|
||||
G_ALIGNOF (guchar),
|
||||
GDK_MEMORY_U8,
|
||||
{ 0, 0, 3, 0 },
|
||||
{ GL_R8, GL_RED, GL_UNSIGNED_BYTE, { GL_ONE, GL_ONE, GL_ONE, GL_RED } },
|
||||
{ GL_R8, GL_RED, GL_UNSIGNED_BYTE, { GL_RED, GL_RED, GL_RED, GL_RED } },
|
||||
a8_to_float,
|
||||
a8_from_float,
|
||||
},
|
||||
[GDK_MEMORY_A16] = {
|
||||
GDK_MEMORY_ALPHA_STRAIGHT,
|
||||
GDK_MEMORY_ALPHA_PREMULTIPLIED,
|
||||
2,
|
||||
G_ALIGNOF (guint16),
|
||||
GDK_MEMORY_U16,
|
||||
{ 0, 0, 3, 0 },
|
||||
{ GL_R16, GL_RED, GL_UNSIGNED_SHORT, { GL_ONE, GL_ONE, GL_ONE, GL_RED } },
|
||||
{ GL_R16, GL_RED, GL_UNSIGNED_SHORT, { GL_RED, GL_RED, GL_RED, GL_RED } },
|
||||
a16_to_float,
|
||||
a16_from_float,
|
||||
},
|
||||
[GDK_MEMORY_A16_FLOAT] = {
|
||||
GDK_MEMORY_ALPHA_PREMULTIPLIED,
|
||||
2,
|
||||
G_ALIGNOF (guint16),
|
||||
GDK_MEMORY_FLOAT16,
|
||||
{ 0, 0, 3, 0 },
|
||||
{ GL_R16F, GL_RED, GL_HALF_FLOAT, { GL_RED, GL_RED, GL_RED, GL_RED } },
|
||||
a16_float_to_float,
|
||||
a16_float_from_float,
|
||||
},
|
||||
[GDK_MEMORY_A32_FLOAT] = {
|
||||
GDK_MEMORY_ALPHA_PREMULTIPLIED,
|
||||
4,
|
||||
G_ALIGNOF (float),
|
||||
GDK_MEMORY_FLOAT32,
|
||||
{ 0, 0, 3, 0 },
|
||||
{ GL_R32F, GL_RED, GL_FLOAT, { GL_RED, GL_RED, GL_RED, GL_RED } },
|
||||
a32_float_to_float,
|
||||
a32_float_from_float,
|
||||
}
|
||||
};
|
||||
|
||||
/* if this fails, somebody forgot to add formats above */
|
||||
G_STATIC_ASSERT (G_N_ELEMENTS (memory_formats) == GDK_MEMORY_N_FORMATS);
|
||||
|
||||
gsize
|
||||
gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format)
|
||||
{
|
||||
@@ -619,6 +704,33 @@ gdk_memory_depth_merge (GdkMemoryDepth depth1,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* gdk_memory_depth_get_alpha_format:
|
||||
* @depth: the depth
|
||||
*
|
||||
* Gets the preferred format to use for rendering masks and other
|
||||
* alpha-only content.
|
||||
*
|
||||
* Returns: the format
|
||||
**/
|
||||
GdkMemoryFormat
|
||||
gdk_memory_depth_get_alpha_format (GdkMemoryDepth depth)
|
||||
{
|
||||
switch (depth)
|
||||
{
|
||||
case GDK_MEMORY_U8:
|
||||
return GDK_MEMORY_A8;
|
||||
case GDK_MEMORY_U16:
|
||||
return GDK_MEMORY_A16;
|
||||
case GDK_MEMORY_FLOAT16:
|
||||
return GDK_MEMORY_A16_FLOAT;
|
||||
case GDK_MEMORY_FLOAT32:
|
||||
return GDK_MEMORY_A32_FLOAT;
|
||||
default:
|
||||
g_return_val_if_reached (GDK_MEMORY_A8);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_memory_format_gl_format (GdkMemoryFormat format,
|
||||
gboolean gles,
|
||||
@@ -700,6 +812,26 @@ gdk_memory_convert (guchar *dest_data,
|
||||
g_assert (dest_format < GDK_MEMORY_N_FORMATS);
|
||||
g_assert (src_format < GDK_MEMORY_N_FORMATS);
|
||||
|
||||
if (src_format == dest_format)
|
||||
{
|
||||
gsize bytes_per_row = src_desc->bytes_per_pixel * width;
|
||||
|
||||
if (bytes_per_row == src_stride && bytes_per_row == dest_stride)
|
||||
{
|
||||
memcpy (dest_data, src_data, bytes_per_row * height);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
memcpy (dest_data, src_data, bytes_per_row);
|
||||
src_data += src_stride;
|
||||
dest_data += dest_stride;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (src_format == GDK_MEMORY_R8G8B8A8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
|
||||
func = r8g8b8a8_to_r8g8b8a8_premultiplied;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8A8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
|
||||
|
||||
@@ -44,6 +44,7 @@ gsize gdk_memory_format_bytes_per_pixel (GdkMemoryFormat
|
||||
GdkMemoryDepth gdk_memory_format_get_depth (GdkMemoryFormat format) G_GNUC_CONST;
|
||||
GdkMemoryDepth gdk_memory_depth_merge (GdkMemoryDepth depth1,
|
||||
GdkMemoryDepth depth2) G_GNUC_CONST;
|
||||
GdkMemoryFormat gdk_memory_depth_get_alpha_format (GdkMemoryDepth depth) G_GNUC_CONST;
|
||||
gboolean gdk_memory_format_gl_format (GdkMemoryFormat format,
|
||||
gboolean gles,
|
||||
guint gl_major,
|
||||
|
||||
@@ -151,6 +151,8 @@ gdk_memory_texture_new (int width,
|
||||
g_return_val_if_fail (height > 0, NULL);
|
||||
g_return_val_if_fail (bytes != NULL, NULL);
|
||||
g_return_val_if_fail (stride >= width * gdk_memory_format_bytes_per_pixel (format), NULL);
|
||||
/* needs to be this complex to support subtexture of the bottom right part */
|
||||
g_return_val_if_fail (g_bytes_get_size (bytes) >= stride * (height - 1) + width * gdk_memory_format_bytes_per_pixel (format), NULL);
|
||||
|
||||
bytes = gdk_memory_sanitize (bytes, width, height, format, stride, &stride);
|
||||
|
||||
|
||||
@@ -21,23 +21,3 @@ void gdk_source_set_static_name_by_id (guint tag,
|
||||
#ifndef I_
|
||||
#define I_(string) g_intern_static_string (string)
|
||||
#endif
|
||||
|
||||
#if !GLIB_CHECK_VERSION (2, 75, 1)
|
||||
static inline gboolean
|
||||
g_set_str (char **str_pointer,
|
||||
const char *new_str)
|
||||
{
|
||||
char *copy;
|
||||
|
||||
if (*str_pointer == new_str ||
|
||||
(*str_pointer && new_str && strcmp (*str_pointer, new_str) == 0))
|
||||
return FALSE;
|
||||
|
||||
copy = g_strdup (new_str);
|
||||
g_free (*str_pointer);
|
||||
*str_pointer = copy;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@ typedef enum
|
||||
* @GDK_TOPLEVEL_STATE_BOTTOM_RESIZABLE: whether the bottom edge is resizable
|
||||
* @GDK_TOPLEVEL_STATE_LEFT_TILED: whether the left edge is tiled
|
||||
* @GDK_TOPLEVEL_STATE_LEFT_RESIZABLE: whether the left edge is resizable
|
||||
* @GDK_TOPLEVEL_STATE_SUSPENDED: the surface is not visible to the user
|
||||
*
|
||||
* Specifies the state of a toplevel surface.
|
||||
*
|
||||
@@ -111,7 +112,8 @@ typedef enum
|
||||
GDK_TOPLEVEL_STATE_BOTTOM_TILED = 1 << 12,
|
||||
GDK_TOPLEVEL_STATE_BOTTOM_RESIZABLE = 1 << 13,
|
||||
GDK_TOPLEVEL_STATE_LEFT_TILED = 1 << 14,
|
||||
GDK_TOPLEVEL_STATE_LEFT_RESIZABLE = 1 << 15
|
||||
GDK_TOPLEVEL_STATE_LEFT_RESIZABLE = 1 << 15,
|
||||
GDK_TOPLEVEL_STATE_SUSPENDED = 1 << 16
|
||||
} GdkToplevelState;
|
||||
|
||||
/**
|
||||
|
||||
@@ -241,6 +241,10 @@ gdk_vulkan_strerror (VkResult result)
|
||||
return "Codec-specific parameters in a requested (VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR)";
|
||||
case VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR:
|
||||
return "The specified video Std header version is not supported. (VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR)";
|
||||
#endif
|
||||
#if VK_HEADER_VERSION >= 246
|
||||
case VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT:
|
||||
return "The provided binary shader code is not compatible with this device. (VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT)";
|
||||
#endif
|
||||
case VK_RESULT_MAX_ENUM:
|
||||
default:
|
||||
@@ -1005,6 +1009,7 @@ gdk_display_load_pipeline_cache (GdkDisplay *display)
|
||||
&result) != VK_SUCCESS)
|
||||
result = VK_NULL_HANDLE;
|
||||
|
||||
g_object_unref (cache_file);
|
||||
g_free (data);
|
||||
g_free (display->vk_pipeline_cache_etag);
|
||||
display->vk_pipeline_cache_etag = etag;
|
||||
@@ -1050,6 +1055,7 @@ gdk_vulkan_save_pipeline_cache (GdkDisplay *display)
|
||||
{
|
||||
g_warning_once ("Failed to create pipeline cache directory");
|
||||
g_free (path);
|
||||
g_free (data);
|
||||
return FALSE;
|
||||
}
|
||||
g_free (path);
|
||||
@@ -1085,6 +1091,7 @@ gdk_vulkan_save_pipeline_cache (GdkDisplay *display)
|
||||
}
|
||||
g_clear_error (&error);
|
||||
g_object_unref (file);
|
||||
g_free (data);
|
||||
|
||||
/* try again */
|
||||
return gdk_vulkan_save_pipeline_cache (display);
|
||||
@@ -1093,10 +1100,12 @@ gdk_vulkan_save_pipeline_cache (GdkDisplay *display)
|
||||
g_warning ("Failed to save pipeline cache: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
g_object_unref (file);
|
||||
g_free (data);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_object_unref (file);
|
||||
g_free (data);
|
||||
g_free (display->vk_pipeline_cache_etag);
|
||||
display->vk_pipeline_cache_etag = etag;
|
||||
|
||||
@@ -1132,12 +1141,15 @@ gdk_display_create_pipeline_cache (GdkDisplay *display)
|
||||
{
|
||||
display->vk_pipeline_cache = gdk_display_load_pipeline_cache (display);
|
||||
|
||||
GDK_VK_CHECK (vkCreatePipelineCache, display->vk_device,
|
||||
&(VkPipelineCacheCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
|
||||
},
|
||||
NULL,
|
||||
&display->vk_pipeline_cache);
|
||||
if (display->vk_pipeline_cache == VK_NULL_HANDLE)
|
||||
{
|
||||
GDK_VK_CHECK (vkCreatePipelineCache, display->vk_device,
|
||||
&(VkPipelineCacheCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
|
||||
},
|
||||
NULL,
|
||||
&display->vk_pipeline_cache);
|
||||
}
|
||||
}
|
||||
|
||||
VkPipelineCache
|
||||
@@ -1633,7 +1645,6 @@ gdk_display_unref_vulkan (GdkDisplay *display)
|
||||
if (display->vulkan_refcount > 0)
|
||||
return;
|
||||
|
||||
display->vk_shader_modules = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
g_hash_table_iter_init (&iter, display->vk_shader_modules);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
@@ -1642,14 +1653,16 @@ gdk_display_unref_vulkan (GdkDisplay *display)
|
||||
value,
|
||||
NULL);
|
||||
}
|
||||
g_hash_table_unref (display->vk_shader_modules);
|
||||
|
||||
if (display->vk_save_pipeline_cache_source)
|
||||
{
|
||||
g_clear_handle_id (&display->vk_save_pipeline_cache_source, g_source_remove);
|
||||
gdk_vulkan_save_pipeline_cache_cb (display);
|
||||
g_assert (display->vk_save_pipeline_cache_source == 0);
|
||||
}
|
||||
vkDestroyPipelineCache (display->vk_device, display->vk_pipeline_cache, NULL);
|
||||
display->vk_device = VK_NULL_HANDLE;
|
||||
display->vk_pipeline_cache = VK_NULL_HANDLE;
|
||||
g_clear_pointer (&display->vk_pipeline_cache_etag, g_free);
|
||||
display->vk_pipeline_cache_size = 0;
|
||||
|
||||
|
||||
@@ -387,6 +387,8 @@ gdk_save_png (GdkTexture *texture)
|
||||
case GDK_MEMORY_G16A16_PREMULTIPLIED:
|
||||
case GDK_MEMORY_G16A16:
|
||||
case GDK_MEMORY_A16:
|
||||
case GDK_MEMORY_A16_FLOAT:
|
||||
case GDK_MEMORY_A32_FLOAT:
|
||||
format = GDK_MEMORY_G16A16;
|
||||
png_format = PNG_COLOR_TYPE_GRAY_ALPHA;
|
||||
depth = 16;
|
||||
|
||||
@@ -259,6 +259,8 @@ static const FormatData format_data[] = {
|
||||
[GDK_MEMORY_G16] = { GDK_MEMORY_G16, 16, 1, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_MINISBLACK },
|
||||
[GDK_MEMORY_A8] = { GDK_MEMORY_G8A8, 8, 2, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_MINISBLACK },
|
||||
[GDK_MEMORY_A16] = { GDK_MEMORY_G16A16, 16, 2, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_MINISBLACK },
|
||||
[GDK_MEMORY_A16_FLOAT] = { GDK_MEMORY_R16G16B16A16_FLOAT, 16, 4, SAMPLEFORMAT_IEEEFP, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
|
||||
[GDK_MEMORY_A32_FLOAT] = { GDK_MEMORY_R32G32B32A32_FLOAT, 32, 4, SAMPLEFORMAT_IEEEFP, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
|
||||
};
|
||||
|
||||
/* if this fails, somebody forgot to add formats above */
|
||||
|
||||
@@ -73,7 +73,10 @@ typedef NSString *CALayerContentsGravity;
|
||||
|
||||
-(void)windowDidMiniaturize:(NSNotification *)aNotification
|
||||
{
|
||||
gdk_synthesize_surface_state (GDK_SURFACE (gdk_surface), 0, GDK_TOPLEVEL_STATE_MINIMIZED);
|
||||
gdk_synthesize_surface_state (GDK_SURFACE (gdk_surface),
|
||||
0,
|
||||
GDK_TOPLEVEL_STATE_MINIMIZED |
|
||||
GDK_TOPLEVEL_STATE_SUSPENDED);
|
||||
}
|
||||
|
||||
-(void)windowDidDeminiaturize:(NSNotification *)aNotification
|
||||
@@ -83,7 +86,10 @@ typedef NSString *CALayerContentsGravity;
|
||||
else if (GDK_IS_MACOS_POPUP_SURFACE (gdk_surface))
|
||||
_gdk_macos_popup_surface_attach_to_parent (GDK_MACOS_POPUP_SURFACE (gdk_surface));
|
||||
|
||||
gdk_synthesize_surface_state (GDK_SURFACE (gdk_surface), GDK_TOPLEVEL_STATE_MINIMIZED, 0);
|
||||
gdk_synthesize_surface_state (GDK_SURFACE (gdk_surface),
|
||||
GDK_TOPLEVEL_STATE_MINIMIZED |
|
||||
GDK_TOPLEVEL_STATE_SUSPENDED,
|
||||
0);
|
||||
}
|
||||
|
||||
-(void)windowDidBecomeKey:(NSNotification *)aNotification
|
||||
|
||||
@@ -27,9 +27,7 @@
|
||||
#include "gdkmacosdisplay.h"
|
||||
#include "gdkmacossurface.h"
|
||||
|
||||
#import <OpenGL/OpenGL.h>
|
||||
#import <OpenGL/gl3.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <epoxy/gl.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
#include "gdkconfig.h"
|
||||
|
||||
#include <OpenGL/gl3.h>
|
||||
#include <OpenGL/CGLIOSurface.h>
|
||||
#include <QuartzCore/QuartzCore.h>
|
||||
|
||||
@@ -499,7 +498,7 @@ gdk_macos_gl_context_begin_frame (GdkDrawContext *context,
|
||||
gdk_gl_context_make_current (GDK_GL_CONTEXT (self));
|
||||
gdk_macos_gl_context_allocate (self);
|
||||
|
||||
GDK_DRAW_CONTEXT_CLASS (gdk_macos_gl_context_parent_class)->begin_frame (context, prefers_high_depth, region);
|
||||
GDK_DRAW_CONTEXT_CLASS (gdk_macos_gl_context_parent_class)->begin_frame (context, depth, region);
|
||||
|
||||
gdk_gl_context_make_current (GDK_GL_CONTEXT (self));
|
||||
CHECK_GL (NULL, glBindFramebuffer (GL_FRAMEBUFFER, self->fbo));
|
||||
|
||||
@@ -2185,8 +2185,9 @@ set_capability_setting (GdkDisplay *display,
|
||||
enum gtk_shell1_capability test)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
int testbit = 1 << (test - 1);
|
||||
|
||||
g_value_set_boolean (value, (display_wayland->shell_capabilities & test) == test);
|
||||
g_value_set_boolean (value, (display_wayland->shell_capabilities & testbit) == testbit);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -620,6 +620,11 @@ xdg_toplevel_configure (void *data,
|
||||
pending_state |= (GDK_TOPLEVEL_STATE_TILED |
|
||||
GDK_TOPLEVEL_STATE_LEFT_TILED);
|
||||
break;
|
||||
#ifdef HAVE_TOPLEVEL_STATE_SUSPENDED
|
||||
case XDG_TOPLEVEL_STATE_SUSPENDED:
|
||||
pending_state |= GDK_TOPLEVEL_STATE_SUSPENDED;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* Unknown state */
|
||||
break;
|
||||
|
||||
@@ -3014,9 +3014,11 @@ gdk_event_translate (MSG *msg,
|
||||
unset_bits = 0;
|
||||
|
||||
if (IsIconic (msg->hwnd))
|
||||
set_bits |= GDK_TOPLEVEL_STATE_MINIMIZED;
|
||||
set_bits |= (GDK_TOPLEVEL_STATE_MINIMIZED |
|
||||
GDK_TOPLEVEL_STATE_SUSPENDED);
|
||||
else
|
||||
unset_bits |= GDK_TOPLEVEL_STATE_MINIMIZED;
|
||||
unset_bits |= (GDK_TOPLEVEL_STATE_MINIMIZED |
|
||||
GDK_TOPLEVEL_STATE_SUSPENDED);
|
||||
|
||||
if (IsZoomed (msg->hwnd))
|
||||
set_bits |= GDK_TOPLEVEL_STATE_MAXIMIZED;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
* Copyright (C) 1998-2002 Tor Lillqvist
|
||||
* Copyright (C) 2023 the GTK team
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -16,13 +17,6 @@
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib/gprintf.h>
|
||||
@@ -45,8 +39,6 @@
|
||||
#include <wintab.h>
|
||||
#include <imm.h>
|
||||
|
||||
static gboolean gdk_synchronize = FALSE;
|
||||
|
||||
/* Whether GDK initialized COM */
|
||||
static gboolean co_initialized = FALSE;
|
||||
|
||||
@@ -56,18 +48,6 @@ static gboolean ole_initialized = FALSE;
|
||||
void
|
||||
_gdk_win32_surfaceing_init (void)
|
||||
{
|
||||
GdkWin32Keymap *win32_keymap;
|
||||
|
||||
win32_keymap = GDK_WIN32_KEYMAP (_gdk_win32_display_get_keymap (_gdk_display));
|
||||
|
||||
if (gdk_synchronize)
|
||||
GdiSetBatchLimit (1);
|
||||
|
||||
_gdk_input_locale = GetKeyboardLayout (0);
|
||||
_gdk_win32_keymap_set_active_layout (win32_keymap, _gdk_input_locale);
|
||||
|
||||
GDK_NOTE (EVENTS, g_print ("input_locale: %p\n", _gdk_input_locale));
|
||||
|
||||
_gdk_win32_clipdrop_init ();
|
||||
|
||||
gdk_dmanipulation_initialize ();
|
||||
|
||||
@@ -194,12 +194,6 @@ gdk_surface_win32_finalize (GObject *object)
|
||||
surface->hicon_small = NULL;
|
||||
}
|
||||
|
||||
if (surface->cache_surface)
|
||||
{
|
||||
cairo_surface_destroy (surface->cache_surface);
|
||||
surface->cache_surface = NULL;
|
||||
}
|
||||
|
||||
_gdk_win32_surface_unregister_dnd (GDK_SURFACE (surface));
|
||||
|
||||
g_assert (surface->transient_owner == NULL);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
* Copyright (C) 2023 the GTK team
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
@@ -15,13 +16,6 @@
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gdk/win32/gdkprivate-win32.h"
|
||||
@@ -289,23 +283,7 @@ struct _GdkWin32Surface
|
||||
*/
|
||||
guint maximizing : 1;
|
||||
|
||||
/* GDK does not keep window contents around, it just draws new
|
||||
* stuff over the window where changes occurred.
|
||||
* cache_surface retains old window contents, because
|
||||
* UpdateLayeredWindow() doesn't do partial redraws.
|
||||
*/
|
||||
cairo_surface_t *cache_surface;
|
||||
|
||||
/* Unlike window-backed surfaces, DIB-backed surface
|
||||
* does not provide a way to query its size,
|
||||
* so we have to remember it ourselves.
|
||||
*/
|
||||
int dib_width;
|
||||
int dib_height;
|
||||
|
||||
HDC hdc;
|
||||
int hdc_count;
|
||||
HBITMAP saved_dc_bitmap; /* Original bitmap for dc */
|
||||
HDC hdc;
|
||||
|
||||
GdkW32DragMoveResizeContext drag_move_resize_context;
|
||||
|
||||
|
||||
@@ -418,12 +418,18 @@ do_net_wm_state_changes (GdkSurface *surface)
|
||||
if (old_state & GDK_TOPLEVEL_STATE_MINIMIZED)
|
||||
{
|
||||
if (!toplevel->have_hidden)
|
||||
unset |= GDK_TOPLEVEL_STATE_MINIMIZED;
|
||||
{
|
||||
unset |= (GDK_TOPLEVEL_STATE_MINIMIZED |
|
||||
GDK_TOPLEVEL_STATE_SUSPENDED);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (toplevel->have_hidden)
|
||||
set |= GDK_TOPLEVEL_STATE_MINIMIZED;
|
||||
{
|
||||
set |= (GDK_TOPLEVEL_STATE_MINIMIZED |
|
||||
GDK_TOPLEVEL_STATE_SUSPENDED);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update edge constraints and tiling */
|
||||
@@ -810,9 +816,12 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
|
||||
* the minimized bit off.
|
||||
*/
|
||||
if (GDK_SURFACE_IS_MAPPED (surface))
|
||||
gdk_synthesize_surface_state (surface,
|
||||
0,
|
||||
GDK_TOPLEVEL_STATE_MINIMIZED);
|
||||
{
|
||||
gdk_synthesize_surface_state (surface,
|
||||
0,
|
||||
GDK_TOPLEVEL_STATE_MINIMIZED |
|
||||
GDK_TOPLEVEL_STATE_SUSPENDED);
|
||||
}
|
||||
}
|
||||
|
||||
if (surface_impl->toplevel &&
|
||||
@@ -841,9 +850,12 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
|
||||
{
|
||||
/* Unset minimized if it was set */
|
||||
if (surface->state & GDK_TOPLEVEL_STATE_MINIMIZED)
|
||||
gdk_synthesize_surface_state (surface,
|
||||
GDK_TOPLEVEL_STATE_MINIMIZED,
|
||||
0);
|
||||
{
|
||||
gdk_synthesize_surface_state (surface,
|
||||
GDK_TOPLEVEL_STATE_MINIMIZED |
|
||||
GDK_TOPLEVEL_STATE_SUSPENDED,
|
||||
0);
|
||||
}
|
||||
|
||||
if (toplevel)
|
||||
gdk_surface_thaw_updates (surface);
|
||||
|
||||
@@ -3270,7 +3270,10 @@ gdk_x11_surface_minimize (GdkSurface *surface)
|
||||
else
|
||||
{
|
||||
/* Flip our client side flag, the real work happens on map. */
|
||||
gdk_synthesize_surface_state (surface, 0, GDK_TOPLEVEL_STATE_MINIMIZED);
|
||||
gdk_synthesize_surface_state (surface,
|
||||
0,
|
||||
GDK_TOPLEVEL_STATE_MINIMIZED |
|
||||
GDK_TOPLEVEL_STATE_SUSPENDED);
|
||||
gdk_wmspec_change_state (TRUE, surface,
|
||||
"_NET_WM_STATE_HIDDEN",
|
||||
NULL);
|
||||
@@ -3293,7 +3296,10 @@ gdk_x11_surface_unminimize (GdkSurface *surface)
|
||||
else
|
||||
{
|
||||
/* Flip our client side flag, the real work happens on map. */
|
||||
gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_MINIMIZED, 0);
|
||||
gdk_synthesize_surface_state (surface,
|
||||
GDK_TOPLEVEL_STATE_MINIMIZED |
|
||||
GDK_TOPLEVEL_STATE_SUSPENDED,
|
||||
0);
|
||||
gdk_wmspec_change_state (FALSE, surface,
|
||||
"_NET_WM_STATE_HIDDEN",
|
||||
NULL);
|
||||
|
||||
@@ -271,6 +271,8 @@ collect_reused_child_nodes (GskRenderer *renderer,
|
||||
case GSK_CROSS_FADE_NODE:
|
||||
case GSK_BLUR_NODE:
|
||||
case GSK_MASK_NODE:
|
||||
case GSK_FILL_NODE:
|
||||
case GSK_STROKE_NODE:
|
||||
|
||||
default:
|
||||
|
||||
@@ -859,6 +861,8 @@ gsk_broadway_renderer_add_node (GskRenderer *renderer,
|
||||
case GSK_CROSS_FADE_NODE:
|
||||
case GSK_BLUR_NODE:
|
||||
case GSK_GL_SHADER_NODE:
|
||||
case GSK_FILL_NODE:
|
||||
case GSK_STROKE_NODE:
|
||||
default:
|
||||
break; /* Fallback */
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#include "gskglcommandqueueprivate.h"
|
||||
#include "gskglcompilerprivate.h"
|
||||
#include "gskglglyphlibraryprivate.h"
|
||||
#include "gskglglyphylibraryprivate.h"
|
||||
#include "gskgliconlibraryprivate.h"
|
||||
#include "gskglprogramprivate.h"
|
||||
#include "gskglshadowlibraryprivate.h"
|
||||
@@ -274,7 +273,6 @@ gsk_gl_driver_dispose (GObject *object)
|
||||
}
|
||||
|
||||
g_clear_object (&self->glyphs_library);
|
||||
g_clear_object (&self->glyphy_library);
|
||||
g_clear_object (&self->icons_library);
|
||||
g_clear_object (&self->shadows_library);
|
||||
|
||||
@@ -465,7 +463,6 @@ gsk_gl_driver_new (GskGLCommandQueue *command_queue,
|
||||
}
|
||||
|
||||
self->glyphs_library = gsk_gl_glyph_library_new (self);
|
||||
self->glyphy_library = gsk_gl_glyphy_library_new (self);
|
||||
self->icons_library = gsk_gl_icon_library_new (self);
|
||||
self->shadows_library = gsk_gl_shadow_library_new (self);
|
||||
|
||||
@@ -576,8 +573,6 @@ gsk_gl_driver_begin_frame (GskGLDriver *self,
|
||||
self->current_frame_id);
|
||||
gsk_gl_texture_library_begin_frame (GSK_GL_TEXTURE_LIBRARY (self->glyphs_library),
|
||||
self->current_frame_id);
|
||||
gsk_gl_texture_library_begin_frame (GSK_GL_TEXTURE_LIBRARY (self->glyphy_library),
|
||||
self->current_frame_id);
|
||||
|
||||
/* Cleanup old shadows */
|
||||
gsk_gl_shadow_library_begin_frame (self->shadows_library);
|
||||
|
||||
@@ -97,7 +97,6 @@ struct _GskGLDriver
|
||||
GskGLCommandQueue *command_queue;
|
||||
|
||||
GskGLGlyphLibrary *glyphs_library;
|
||||
GskGLGlyphyLibrary *glyphy_library;
|
||||
GskGLIconLibrary *icons_library;
|
||||
GskGLShadowLibrary *shadows_library;
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include "gskgldriverprivate.h"
|
||||
#include "gskglglyphlibraryprivate.h"
|
||||
|
||||
#include "gskdebugprivate.h"
|
||||
|
||||
#define MAX_GLYPH_SIZE 128
|
||||
|
||||
G_DEFINE_TYPE (GskGLGlyphLibrary, gsk_gl_glyph_library, GSK_TYPE_GL_TEXTURE_LIBRARY)
|
||||
@@ -407,6 +409,8 @@ gsk_gl_glyph_library_add (GskGLGlyphLibrary *self,
|
||||
width = (int) ceil (ink_rect.width * key->scale / 1024.0);
|
||||
height = (int) ceil (ink_rect.height * key->scale / 1024.0);
|
||||
|
||||
GSK_DEBUG (GLYPH_CACHE, "font %p glyph %u: %u x %u pixels", key->font, key->glyph, width, height);
|
||||
|
||||
value = gsk_gl_texture_library_pack (tl,
|
||||
key,
|
||||
sizeof *value,
|
||||
|
||||
@@ -1,544 +0,0 @@
|
||||
/* gskglglyphylibrary.c
|
||||
*
|
||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
/* Some of the glyphy cache is based upon the original glyphy code.
|
||||
* It's license is provided below.
|
||||
*/
|
||||
/*
|
||||
* Copyright 2012 Google, Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gdk/gdkglcontextprivate.h>
|
||||
#include <gdk/gdkmemoryformatprivate.h>
|
||||
#include <gdk/gdkprofilerprivate.h>
|
||||
|
||||
#include "gskglcommandqueueprivate.h"
|
||||
#include "gskgldriverprivate.h"
|
||||
#include "gskglglyphylibraryprivate.h"
|
||||
#include "gskdebugprivate.h"
|
||||
|
||||
#include "gskpathprivate.h"
|
||||
|
||||
#include <glyphy.h>
|
||||
|
||||
#define TOLERANCE (1/2048.)
|
||||
#define MIN_FONT_SIZE 14
|
||||
#define GRID_SIZE 20 /* Per EM */
|
||||
#define ENLIGHTEN_MAX .01 /* Per EM */
|
||||
#define EMBOLDEN_MAX .024 /* Per EM */
|
||||
|
||||
/* We split the atlas into cells of size 64x8, so the minimum number of
|
||||
* bytes we store per glyph is 2048, and an atlas of size 2048x1024 can
|
||||
* hold at most 4096 glyphs. We need 5 and 7 bits to store the position
|
||||
* of a glyph in the atlas.
|
||||
*
|
||||
* We allocate each glyph a column of as many vertically adjacent cells
|
||||
* as it needs.
|
||||
*/
|
||||
#define ITEM_W 64
|
||||
#define ITEM_H_QUANTUM 8
|
||||
|
||||
G_DEFINE_TYPE (GskGLGlyphyLibrary, gsk_gl_glyphy_library, GSK_TYPE_GL_TEXTURE_LIBRARY)
|
||||
|
||||
GskGLGlyphyLibrary *
|
||||
gsk_gl_glyphy_library_new (GskGLDriver *driver)
|
||||
{
|
||||
g_return_val_if_fail (GSK_IS_GL_DRIVER (driver), NULL);
|
||||
|
||||
return g_object_new (GSK_TYPE_GL_GLYPHY_LIBRARY,
|
||||
"driver", driver,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static guint
|
||||
gsk_gl_glyphy_key_hash (gconstpointer data)
|
||||
{
|
||||
const GskGLGlyphyKey *key = data;
|
||||
|
||||
/* malloc()'d pointers already guarantee 3 bits from the LSB on 64-bit and
|
||||
* 2 bits from the LSB on 32-bit. Shift by enough to give us 256 entries
|
||||
* in our front cache for the glyph since languages will naturally cluster
|
||||
* for us.
|
||||
*/
|
||||
|
||||
return (key->font << 8) ^ key->glyph;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_gl_glyphy_key_equal (gconstpointer v1,
|
||||
gconstpointer v2)
|
||||
{
|
||||
return memcmp (v1, v2, sizeof (GskGLGlyphyKey)) == 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_glyphy_key_free (gpointer data)
|
||||
{
|
||||
GskGLGlyphyKey *key = data;
|
||||
|
||||
g_slice_free (GskGLGlyphyKey, key);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_glyphy_value_free (gpointer data)
|
||||
{
|
||||
g_slice_free (GskGLGlyphyValue, data);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_glyphy_library_clear_cache (GskGLTextureLibrary *library)
|
||||
{
|
||||
GskGLGlyphyLibrary *self = (GskGLGlyphyLibrary *)library;
|
||||
|
||||
g_assert (GSK_IS_GL_GLYPHY_LIBRARY (self));
|
||||
|
||||
memset (self->front, 0, sizeof self->front);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_glyphy_library_init_atlas (GskGLTextureLibrary *library,
|
||||
GskGLTextureAtlas *atlas)
|
||||
{
|
||||
g_assert (GSK_IS_GL_GLYPHY_LIBRARY (library));
|
||||
g_assert (atlas != NULL);
|
||||
|
||||
atlas->cursor_x = 0;
|
||||
atlas->cursor_y = 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_gl_glyphy_library_allocate (GskGLTextureLibrary *library,
|
||||
GskGLTextureAtlas *atlas,
|
||||
int width,
|
||||
int height,
|
||||
int *out_x,
|
||||
int *out_y)
|
||||
{
|
||||
GskGLGlyphyLibrary *self = (GskGLGlyphyLibrary *)library;
|
||||
int cursor_save_x;
|
||||
int cursor_save_y;
|
||||
|
||||
g_assert (GSK_IS_GL_GLYPHY_LIBRARY (self));
|
||||
g_assert (atlas != NULL);
|
||||
|
||||
cursor_save_x = atlas->cursor_x;
|
||||
cursor_save_y = atlas->cursor_y;
|
||||
|
||||
if ((height & (self->item_h_q-1)) != 0)
|
||||
height = (height + self->item_h_q - 1) & ~(self->item_h_q - 1);
|
||||
|
||||
/* Require allocations in columns of 64 and rows of 8 */
|
||||
g_assert (width == self->item_w);
|
||||
g_assert ((height % self->item_h_q) == 0);
|
||||
|
||||
if (atlas->cursor_y + height > atlas->height)
|
||||
{
|
||||
/* Go to next column */
|
||||
atlas->cursor_x += self->item_w;
|
||||
atlas->cursor_y = 0;
|
||||
}
|
||||
|
||||
if (atlas->cursor_x + width <= atlas->width &&
|
||||
atlas->cursor_y + height <= atlas->height)
|
||||
{
|
||||
*out_x = atlas->cursor_x;
|
||||
*out_y = atlas->cursor_y;
|
||||
atlas->cursor_y += height;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
atlas->cursor_x = cursor_save_x;
|
||||
atlas->cursor_y = cursor_save_y;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_glyphy_library_finalize (GObject *object)
|
||||
{
|
||||
GskGLGlyphyLibrary *self = (GskGLGlyphyLibrary *)object;
|
||||
|
||||
g_clear_pointer (&self->acc, glyphy_arc_accumulator_destroy);
|
||||
g_clear_pointer (&self->acc_endpoints, g_array_unref);
|
||||
|
||||
G_OBJECT_CLASS (gsk_gl_glyphy_library_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
GQuark quark_glyphy_font_key;
|
||||
|
||||
static void
|
||||
gsk_gl_glyphy_library_class_init (GskGLGlyphyLibraryClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GskGLTextureLibraryClass *library_class = GSK_GL_TEXTURE_LIBRARY_CLASS (klass);
|
||||
|
||||
quark_glyphy_font_key = g_quark_from_static_string ("glyphy-font-key");
|
||||
|
||||
object_class->finalize = gsk_gl_glyphy_library_finalize;
|
||||
|
||||
library_class->allocate = gsk_gl_glyphy_library_allocate;
|
||||
library_class->clear_cache = gsk_gl_glyphy_library_clear_cache;
|
||||
library_class->init_atlas = gsk_gl_glyphy_library_init_atlas;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_glyphy_library_init (GskGLGlyphyLibrary *self)
|
||||
{
|
||||
GskGLTextureLibrary *tl = (GskGLTextureLibrary *)self;
|
||||
|
||||
tl->max_entry_size = 0;
|
||||
tl->max_frame_age = 512;
|
||||
tl->atlas_width = 2048;
|
||||
tl->atlas_height = 1024;
|
||||
gsk_gl_texture_library_set_funcs (tl,
|
||||
gsk_gl_glyphy_key_hash,
|
||||
gsk_gl_glyphy_key_equal,
|
||||
gsk_gl_glyphy_key_free,
|
||||
gsk_gl_glyphy_value_free);
|
||||
|
||||
self->acc = glyphy_arc_accumulator_create ();
|
||||
self->acc_endpoints = g_array_new (FALSE, FALSE, sizeof (glyphy_arc_endpoint_t));
|
||||
self->item_w = ITEM_W;
|
||||
self->item_h_q = ITEM_H_QUANTUM;
|
||||
}
|
||||
|
||||
static glyphy_bool_t
|
||||
accumulate_endpoint (glyphy_arc_endpoint_t *endpoint,
|
||||
GArray *endpoints)
|
||||
{
|
||||
g_array_append_vals (endpoints, endpoint, 1);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
move_to (hb_draw_funcs_t *dfuncs,
|
||||
GskPathBuilder *builder,
|
||||
hb_draw_state_t *st,
|
||||
float x,
|
||||
float y,
|
||||
void *data)
|
||||
{
|
||||
gsk_path_builder_move_to (builder, x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
line_to (hb_draw_funcs_t *dfuncs,
|
||||
GskPathBuilder *builder,
|
||||
hb_draw_state_t *st,
|
||||
float x,
|
||||
float y,
|
||||
void *data)
|
||||
{
|
||||
gsk_path_builder_line_to (builder, x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
cubic_to (hb_draw_funcs_t *dfuncs,
|
||||
GskPathBuilder *builder,
|
||||
hb_draw_state_t *st,
|
||||
float x1,
|
||||
float y1,
|
||||
float x2,
|
||||
float y2,
|
||||
float x3,
|
||||
float y3,
|
||||
void *data)
|
||||
{
|
||||
gsk_path_builder_cubic_to (builder, x1, y1, x2, y2, x3, y3);
|
||||
}
|
||||
|
||||
static void
|
||||
close_path (hb_draw_funcs_t *dfuncs,
|
||||
GskPathBuilder *builder,
|
||||
hb_draw_state_t *st,
|
||||
void *data)
|
||||
{
|
||||
gsk_path_builder_close (builder);
|
||||
}
|
||||
|
||||
static hb_draw_funcs_t *
|
||||
gsk_path_get_draw_funcs (void)
|
||||
{
|
||||
static hb_draw_funcs_t *funcs = NULL;
|
||||
|
||||
if (!funcs)
|
||||
{
|
||||
funcs = hb_draw_funcs_create ();
|
||||
|
||||
hb_draw_funcs_set_move_to_func (funcs, (hb_draw_move_to_func_t) move_to, NULL, NULL);
|
||||
hb_draw_funcs_set_line_to_func (funcs, (hb_draw_line_to_func_t) line_to, NULL, NULL);
|
||||
hb_draw_funcs_set_cubic_to_func (funcs, (hb_draw_cubic_to_func_t) cubic_to, NULL, NULL);
|
||||
hb_draw_funcs_set_close_path_func (funcs, (hb_draw_close_path_func_t) close_path, NULL, NULL);
|
||||
|
||||
hb_draw_funcs_make_immutable (funcs);
|
||||
}
|
||||
|
||||
return funcs;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
acc_callback (GskPathOperation op,
|
||||
const graphene_point_t *pts,
|
||||
gsize n_pts,
|
||||
float weight,
|
||||
gpointer user_data)
|
||||
{
|
||||
glyphy_arc_accumulator_t *acc = user_data;
|
||||
glyphy_point_t p0, p1, p2, p3;
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case GSK_PATH_MOVE:
|
||||
p0.x = pts[0].x; p0.y = pts[0].y;
|
||||
glyphy_arc_accumulator_move_to (acc, &p0);
|
||||
break;
|
||||
case GSK_PATH_CLOSE:
|
||||
glyphy_arc_accumulator_close_path (acc);
|
||||
break;
|
||||
case GSK_PATH_LINE:
|
||||
p1.x = pts[1].x; p1.y = pts[1].y;
|
||||
glyphy_arc_accumulator_line_to (acc, &p1);
|
||||
break;
|
||||
case GSK_PATH_QUAD:
|
||||
p1.x = pts[1].x; p1.y = pts[1].y;
|
||||
p2.x = pts[2].x; p2.y = pts[2].y;
|
||||
/* This glyphy api is mis-named */
|
||||
glyphy_arc_accumulator_conic_to (acc, &p1, &p2);
|
||||
break;
|
||||
case GSK_PATH_CUBIC:
|
||||
p1.x = pts[1].x; p1.y = pts[1].y;
|
||||
p2.x = pts[2].x; p2.y = pts[2].y;
|
||||
p3.x = pts[3].x; p3.y = pts[3].y;
|
||||
glyphy_arc_accumulator_cubic_to (acc, &p1, &p2, &p3);
|
||||
break;
|
||||
case GSK_PATH_CONIC:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
encode_glyph (GskGLGlyphyLibrary *self,
|
||||
hb_font_t *font,
|
||||
unsigned int glyph_index,
|
||||
double tolerance_per_em,
|
||||
glyphy_rgba_t *buffer,
|
||||
guint buffer_len,
|
||||
guint *output_len,
|
||||
guint *nominal_width,
|
||||
guint *nominal_height,
|
||||
glyphy_extents_t *extents)
|
||||
{
|
||||
hb_face_t *face = hb_font_get_face (font);
|
||||
guint upem = hb_face_get_upem (face);
|
||||
double tolerance = upem * tolerance_per_em;
|
||||
double faraway = (double)upem / (MIN_FONT_SIZE * M_SQRT2);
|
||||
double unit_size = (double) upem / GRID_SIZE;
|
||||
double enlighten_max = (double) upem * ENLIGHTEN_MAX;
|
||||
double embolden_max = (double) upem * EMBOLDEN_MAX;
|
||||
double avg_fetch_achieved;
|
||||
GskPathBuilder *builder;
|
||||
GskPath *path, *simplified;
|
||||
|
||||
self->acc_endpoints->len = 0;
|
||||
|
||||
glyphy_arc_accumulator_reset (self->acc);
|
||||
glyphy_arc_accumulator_set_tolerance (self->acc, tolerance);
|
||||
glyphy_arc_accumulator_set_callback (self->acc,
|
||||
(glyphy_arc_endpoint_accumulator_callback_t)accumulate_endpoint,
|
||||
self->acc_endpoints);
|
||||
|
||||
builder = gsk_path_builder_new ();
|
||||
#if HB_VERSION_ATLEAST (7, 0, 0)
|
||||
hb_font_draw_glyph (font, glyph_index, gsk_path_get_draw_funcs (), builder);
|
||||
#else
|
||||
hb_font_get_glyph_shape (font, glyph_index, gsk_path_get_draw_funcs (), builder);
|
||||
#endif
|
||||
path = gsk_path_builder_free_to_path (builder);
|
||||
simplified = gsk_path_op (GSK_PATH_OP_SIMPLIFY, GSK_FILL_RULE_WINDING, path, NULL);
|
||||
gsk_path_foreach (simplified, -1, acc_callback, self->acc);
|
||||
gsk_path_unref (simplified);
|
||||
gsk_path_unref (path);
|
||||
|
||||
if (!glyphy_arc_accumulator_successful (self->acc))
|
||||
return FALSE;
|
||||
|
||||
g_assert (glyphy_arc_accumulator_get_error (self->acc) <= tolerance);
|
||||
|
||||
if (self->acc_endpoints->len > 0)
|
||||
glyphy_outline_winding_from_even_odd ((gpointer)self->acc_endpoints->data,
|
||||
self->acc_endpoints->len,
|
||||
FALSE);
|
||||
|
||||
if (!glyphy_arc_list_encode_blob2 ((gpointer)self->acc_endpoints->data,
|
||||
self->acc_endpoints->len,
|
||||
buffer,
|
||||
buffer_len,
|
||||
faraway,
|
||||
unit_size,
|
||||
enlighten_max,
|
||||
embolden_max,
|
||||
&avg_fetch_achieved,
|
||||
output_len,
|
||||
nominal_width,
|
||||
nominal_height,
|
||||
extents))
|
||||
return FALSE;
|
||||
|
||||
glyphy_extents_scale (extents, 1./upem, 1./upem);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline hb_font_t *
|
||||
get_nominal_size_hb_font (PangoFont *font)
|
||||
{
|
||||
hb_font_t *hbfont;
|
||||
const float *coords;
|
||||
unsigned int length;
|
||||
|
||||
hbfont = (hb_font_t *) g_object_get_data ((GObject *)font, "glyph-nominal-size-font");
|
||||
if (hbfont == NULL)
|
||||
{
|
||||
hbfont = hb_font_create (hb_font_get_face (pango_font_get_hb_font (font)));
|
||||
coords = hb_font_get_var_coords_design (pango_font_get_hb_font (font), &length);
|
||||
if (length > 0)
|
||||
hb_font_set_var_coords_design (hbfont, coords, length);
|
||||
|
||||
g_object_set_data_full ((GObject *)font, "glyphy-nominal-size-font",
|
||||
hbfont, (GDestroyNotify)hb_font_destroy);
|
||||
}
|
||||
|
||||
return hbfont;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_gl_glyphy_library_add (GskGLGlyphyLibrary *self,
|
||||
GskGLGlyphyKey *key,
|
||||
PangoFont *font,
|
||||
const GskGLGlyphyValue **out_value)
|
||||
{
|
||||
static glyphy_rgba_t buffer[4096 * 16];
|
||||
GskGLTextureLibrary *tl = (GskGLTextureLibrary *)self;
|
||||
GskGLGlyphyValue *value;
|
||||
glyphy_extents_t extents;
|
||||
hb_font_t *hbfont;
|
||||
guint packed_x;
|
||||
guint packed_y;
|
||||
guint nominal_w, nominal_h;
|
||||
guint output_len = 0;
|
||||
guint texture_id;
|
||||
guint width, height;
|
||||
|
||||
g_assert (GSK_IS_GL_GLYPHY_LIBRARY (self));
|
||||
g_assert (key != NULL);
|
||||
g_assert (font != NULL);
|
||||
g_assert (out_value != NULL);
|
||||
|
||||
hbfont = get_nominal_size_hb_font (font);
|
||||
|
||||
/* Convert the glyph to a list of arcs */
|
||||
if (!encode_glyph (self, hbfont, key->glyph, TOLERANCE,
|
||||
buffer, sizeof buffer, &output_len,
|
||||
&nominal_w, &nominal_h, &extents))
|
||||
return FALSE;
|
||||
|
||||
/* Allocate space for list within atlas */
|
||||
width = self->item_w;
|
||||
height = (output_len + width - 1) / width;
|
||||
GSK_DEBUG (GLYPH_CACHE, "font %u glyph %u: %u bytes (%u x %u)", key->font, key->glyph, output_len * 4, width, height);
|
||||
|
||||
value = gsk_gl_texture_library_pack (tl, key, sizeof *value,
|
||||
width, height, 0,
|
||||
&packed_x, &packed_y);
|
||||
|
||||
g_assert (packed_x % ITEM_W == 0);
|
||||
g_assert (packed_y % ITEM_H_QUANTUM == 0);
|
||||
|
||||
/* Make sure we found space to pack */
|
||||
texture_id = GSK_GL_TEXTURE_ATLAS_ENTRY_TEXTURE (value);
|
||||
if (texture_id == 0)
|
||||
return FALSE;
|
||||
|
||||
if (!glyphy_extents_is_empty (&extents))
|
||||
{
|
||||
/* Connect the texture for data upload */
|
||||
glActiveTexture (GL_TEXTURE0);
|
||||
glBindTexture (GL_TEXTURE_2D, texture_id);
|
||||
|
||||
g_assert (width > 0);
|
||||
g_assert (height > 0);
|
||||
|
||||
/* Upload the arc list */
|
||||
if (width * height == output_len)
|
||||
{
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
packed_x, packed_y,
|
||||
width, height,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
packed_x, packed_y,
|
||||
width, height - 1,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
buffer);
|
||||
/* Upload the last row separately */
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
packed_x, packed_y + height - 1,
|
||||
output_len - (width * (height - 1)), 1,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
buffer + (width * (height - 1)));
|
||||
}
|
||||
}
|
||||
|
||||
value->extents.min_x = extents.min_x;
|
||||
value->extents.min_y = extents.min_y;
|
||||
value->extents.max_x = extents.max_x;
|
||||
value->extents.max_y = extents.max_y;
|
||||
value->nominal_w = nominal_w;
|
||||
value->nominal_h = nominal_h;
|
||||
value->atlas_x = packed_x / self->item_w;
|
||||
value->atlas_y = packed_y / self->item_h_q;
|
||||
|
||||
*out_value = value;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
/* gskglglyphylibraryprivate.h
|
||||
*
|
||||
* Copyright 2020-2022 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GSK_GL_GLYPHY_LIBRARY_PRIVATE_H__
|
||||
#define __GSK_GL_GLYPHY_LIBRARY_PRIVATE_H__
|
||||
|
||||
#include <glyphy.h>
|
||||
#include <pango/pango.h>
|
||||
|
||||
#include "gskgltexturelibraryprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GSK_TYPE_GL_GLYPHY_LIBRARY (gsk_gl_glyphy_library_get_type())
|
||||
|
||||
typedef guint FontKey;
|
||||
|
||||
extern GQuark quark_glyphy_font_key;
|
||||
|
||||
static inline FontKey
|
||||
gsk_gl_glyphy_library_get_font_key (PangoFont *font)
|
||||
{
|
||||
FontKey key;
|
||||
|
||||
key = (FontKey) GPOINTER_TO_UINT (g_object_get_qdata ((GObject *)font, quark_glyphy_font_key));
|
||||
if (key == 0)
|
||||
{
|
||||
PangoFontDescription *desc = pango_font_describe (font);
|
||||
pango_font_description_set_size (desc, 10 * PANGO_SCALE);
|
||||
key = (FontKey) pango_font_description_hash (desc);
|
||||
pango_font_description_free (desc);
|
||||
g_object_set_qdata ((GObject *)font, quark_glyphy_font_key, GUINT_TO_POINTER (key));
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
static inline float
|
||||
gsk_gl_glyphy_library_get_font_scale (PangoFont *font)
|
||||
{
|
||||
hb_font_t *hbfont;
|
||||
int x_scale, y_scale;
|
||||
|
||||
hbfont = pango_font_get_hb_font (font);
|
||||
hb_font_get_scale (hbfont, &x_scale, &y_scale);
|
||||
|
||||
return MAX (x_scale, y_scale) / 1000.0;
|
||||
}
|
||||
|
||||
|
||||
typedef struct _GskGLGlyphyKey
|
||||
{
|
||||
FontKey font;
|
||||
PangoGlyph glyph;
|
||||
} GskGLGlyphyKey;
|
||||
|
||||
typedef struct _GskGLGlyphyValue
|
||||
{
|
||||
GskGLTextureAtlasEntry entry;
|
||||
struct {
|
||||
float min_x;
|
||||
float min_y;
|
||||
float max_x;
|
||||
float max_y;
|
||||
} extents;
|
||||
guint nominal_w;
|
||||
guint nominal_h;
|
||||
guint atlas_x;
|
||||
guint atlas_y;
|
||||
} GskGLGlyphyValue;
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GskGLGlyphyLibrary, gsk_gl_glyphy_library, GSK, GL_GLYPHY_LIBRARY, GskGLTextureLibrary)
|
||||
|
||||
struct _GskGLGlyphyLibrary
|
||||
{
|
||||
GskGLTextureLibrary parent_instance;
|
||||
glyphy_arc_accumulator_t *acc;
|
||||
GArray *acc_endpoints;
|
||||
guint item_w;
|
||||
guint item_h_q;
|
||||
struct {
|
||||
GskGLGlyphyKey key;
|
||||
const GskGLGlyphyValue *value;
|
||||
} front[256];
|
||||
};
|
||||
|
||||
GskGLGlyphyLibrary *gsk_gl_glyphy_library_new (GskGLDriver *driver);
|
||||
gboolean gsk_gl_glyphy_library_add (GskGLGlyphyLibrary *self,
|
||||
GskGLGlyphyKey *key,
|
||||
PangoFont *font,
|
||||
const GskGLGlyphyValue **out_value);
|
||||
|
||||
static inline guint
|
||||
gsk_gl_glyphy_library_lookup_or_add (GskGLGlyphyLibrary *self,
|
||||
const GskGLGlyphyKey *key,
|
||||
PangoFont *font,
|
||||
const GskGLGlyphyValue **out_value)
|
||||
{
|
||||
GskGLTextureAtlasEntry *entry;
|
||||
guint front_index = key->glyph & 0xFF;
|
||||
|
||||
if (memcmp (key, &self->front[front_index], sizeof *key) == 0)
|
||||
{
|
||||
*out_value = self->front[front_index].value;
|
||||
}
|
||||
else if (gsk_gl_texture_library_lookup ((GskGLTextureLibrary *)self, key, &entry))
|
||||
{
|
||||
*out_value = (GskGLGlyphyValue *)entry;
|
||||
self->front[front_index].key = *key;
|
||||
self->front[front_index].value = *out_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
GskGLGlyphyKey *k = g_slice_copy (sizeof *key, key);
|
||||
gsk_gl_glyphy_library_add (self, k, font, out_value);
|
||||
self->front[front_index].key = *key;
|
||||
self->front[front_index].value = *out_value;
|
||||
}
|
||||
|
||||
return GSK_GL_TEXTURE_ATLAS_ENTRY_TEXTURE (*out_value);
|
||||
}
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_GL_GLYPHY_LIBRARY_PRIVATE_H__ */
|
||||
@@ -87,21 +87,3 @@ GSK_GL_DEFINE_PROGRAM (unblurred_outset_shadow,
|
||||
GSK_GL_ADD_UNIFORM (1, UNBLURRED_OUTSET_SHADOW_SPREAD, u_spread)
|
||||
GSK_GL_ADD_UNIFORM (2, UNBLURRED_OUTSET_SHADOW_OFFSET, u_offset)
|
||||
GSK_GL_ADD_UNIFORM (3, UNBLURRED_OUTSET_SHADOW_OUTLINE_RECT, u_outline_rect))
|
||||
|
||||
GSK_GL_DEFINE_PROGRAM (glyphy,
|
||||
GSK_GL_SHADER_JOINED (VERTEX,
|
||||
GSK_GL_SHADER_RESOURCE ("glyphy.vs.glsl"),
|
||||
NULL)
|
||||
GSK_GL_SHADER_JOINED (FRAGMENT,
|
||||
GSK_GL_SHADER_RESOURCE ("glyphy.atlas.glsl"),
|
||||
GSK_GL_SHADER_STRING (glyphy_common_shader_source ()),
|
||||
GSK_GL_SHADER_STRING ("#define GLYPHY_SDF_PSEUDO_DISTANCE 1\n"),
|
||||
GSK_GL_SHADER_STRING (glyphy_sdf_shader_source ()),
|
||||
GSK_GL_SHADER_RESOURCE ("glyphy.fs.glsl"),
|
||||
NULL),
|
||||
GSK_GL_ADD_UNIFORM (0, GLYPHY_CONTRAST, u_contrast)
|
||||
GSK_GL_ADD_UNIFORM (1, GLYPHY_GAMMA_ADJUST, u_gamma_adjust)
|
||||
GSK_GL_ADD_UNIFORM (2, GLYPHY_OUTLINE_THICKNESS, u_outline_thickness)
|
||||
GSK_GL_ADD_UNIFORM (3, GLYPHY_OUTLINE, u_outline)
|
||||
GSK_GL_ADD_UNIFORM (4, GLYPHY_BOLDNESS, u_boldness)
|
||||
GSK_GL_ADD_UNIFORM (6, GLYPHY_ATLAS_INFO, u_atlas_info))
|
||||
|
||||
@@ -150,13 +150,6 @@ gsk_gl_renderer_realize (GskRenderer *renderer,
|
||||
gsk_gl_command_queue_set_profiler (self->command_queue,
|
||||
gsk_renderer_get_profiler (renderer));
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (gsk_renderer_get_debug_flags (renderer) & GSK_DEBUG_NO_GLYPHY)
|
||||
GSK_RENDERER_DEBUG (renderer, RENDERER, "GL Renderer will use cairo for glyph rendering");
|
||||
else
|
||||
GSK_RENDERER_DEBUG (renderer, RENDERER, "GL Renderer will use glyphy for glyph rendering");
|
||||
#endif
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
failure:
|
||||
@@ -314,15 +307,10 @@ gsk_gl_renderer_render (GskRenderer *renderer,
|
||||
|
||||
gsk_gl_driver_begin_frame (self->driver, self->command_queue);
|
||||
job = gsk_gl_render_job_new (self->driver, &viewport, scale, render_region, 0, clear_framebuffer);
|
||||
|
||||
if ((gsk_renderer_get_debug_flags (renderer) & GSK_DEBUG_NO_GLYPHY) == 0)
|
||||
gsk_gl_render_job_set_use_glyphy (job, TRUE);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GSK_RENDERER_DEBUG_CHECK (GSK_RENDERER (self), FALLBACK))
|
||||
gsk_gl_render_job_set_debug_fallback (job, TRUE);
|
||||
#endif
|
||||
|
||||
gsk_gl_render_job_render (job, root);
|
||||
gsk_gl_driver_end_frame (self->driver);
|
||||
gsk_gl_render_job_free (job);
|
||||
|
||||
@@ -32,16 +32,13 @@
|
||||
#include <gdk/gdkmemorytextureprivate.h>
|
||||
#include <gsk/gsktransformprivate.h>
|
||||
#include <gsk/gskroundedrectprivate.h>
|
||||
#include <gsk/gskrectprivate.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_PANGOFT
|
||||
#include <pango/pangofc-font.h>
|
||||
#endif
|
||||
|
||||
#include "gskglcommandqueueprivate.h"
|
||||
#include "gskgldriverprivate.h"
|
||||
#include "gskglglyphlibraryprivate.h"
|
||||
#include "gskglglyphylibraryprivate.h"
|
||||
#include "gskgliconlibraryprivate.h"
|
||||
#include "gskglprogramprivate.h"
|
||||
#include "gskglrenderjobprivate.h"
|
||||
@@ -153,9 +150,6 @@ struct _GskGLRenderJob
|
||||
*/
|
||||
guint clear_framebuffer : 1;
|
||||
|
||||
/* Allow experimental glyph rendering with glyphy */
|
||||
guint use_glyphy : 1;
|
||||
|
||||
/* Format we want to use for intermediate textures, determined by
|
||||
* looking at the format of the framebuffer we are rendering on.
|
||||
*/
|
||||
@@ -261,6 +255,8 @@ node_supports_2d_transform (const GskRenderNode *node)
|
||||
case GSK_BLEND_NODE:
|
||||
case GSK_BLUR_NODE:
|
||||
case GSK_MASK_NODE:
|
||||
case GSK_FILL_NODE:
|
||||
case GSK_STROKE_NODE:
|
||||
return TRUE;
|
||||
|
||||
case GSK_SHADOW_NODE:
|
||||
@@ -315,6 +311,8 @@ node_supports_transform (const GskRenderNode *node)
|
||||
case GSK_BLEND_NODE:
|
||||
case GSK_BLUR_NODE:
|
||||
case GSK_MASK_NODE:
|
||||
case GSK_FILL_NODE:
|
||||
case GSK_STROKE_NODE:
|
||||
return TRUE;
|
||||
|
||||
case GSK_SHADOW_NODE:
|
||||
@@ -360,31 +358,6 @@ color_matrix_modifies_alpha (const GskRenderNode *node)
|
||||
return !graphene_vec4_equal (graphene_vec4_w_axis (), &row3);
|
||||
}
|
||||
|
||||
static inline gboolean G_GNUC_PURE
|
||||
rect_contains_rect (const graphene_rect_t *r1,
|
||||
const graphene_rect_t *r2)
|
||||
{
|
||||
return r2->origin.x >= r1->origin.x &&
|
||||
(r2->origin.x + r2->size.width) <= (r1->origin.x + r1->size.width) &&
|
||||
r2->origin.y >= r1->origin.y &&
|
||||
(r2->origin.y + r2->size.height) <= (r1->origin.y + r1->size.height);
|
||||
}
|
||||
|
||||
static inline gboolean G_GNUC_PURE
|
||||
rect_intersects (const graphene_rect_t *r1,
|
||||
const graphene_rect_t *r2)
|
||||
{
|
||||
/* Assume both rects are already normalized, as they usually are */
|
||||
if (r1->origin.x > (r2->origin.x + r2->size.width) ||
|
||||
(r1->origin.x + r1->size.width) < r2->origin.x)
|
||||
return FALSE;
|
||||
else if (r1->origin.y > (r2->origin.y + r2->size.height) ||
|
||||
(r1->origin.y + r1->size.height) < r2->origin.y)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline void
|
||||
init_projection_matrix (graphene_matrix_t *projection,
|
||||
const graphene_rect_t *viewport)
|
||||
@@ -920,7 +893,7 @@ gsk_gl_render_job_update_clip (GskGLRenderJob *job,
|
||||
|
||||
gsk_gl_render_job_transform_bounds (job, bounds, &transformed_bounds);
|
||||
|
||||
if (!rect_intersects (&job->current_clip->rect.bounds, &transformed_bounds))
|
||||
if (!gsk_rect_intersects (&job->current_clip->rect.bounds, &transformed_bounds))
|
||||
{
|
||||
/* Completely clipped away */
|
||||
return FALSE;
|
||||
@@ -928,7 +901,7 @@ gsk_gl_render_job_update_clip (GskGLRenderJob *job,
|
||||
|
||||
if (job->current_clip->is_rectilinear)
|
||||
{
|
||||
if (rect_contains_rect (&job->current_clip->rect.bounds, &transformed_bounds))
|
||||
if (gsk_rect_contains_rect (&job->current_clip->rect.bounds, &transformed_bounds))
|
||||
no_clip = TRUE;
|
||||
else
|
||||
rect_clip = TRUE;
|
||||
@@ -1272,9 +1245,9 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
|
||||
done:
|
||||
if (scale_x < 0 || scale_y < 0)
|
||||
{
|
||||
GskTransform *transform = gsk_transform_translate (NULL,
|
||||
&GRAPHENE_POINT_INIT (scale_x < 0 ? - surface_width : 0,
|
||||
scale_y < 0 ? - surface_height : 0));
|
||||
GskTransform *transform = gsk_transform_translate (gsk_transform_scale (NULL, scale_x < 0 ? -1 : 1, scale_y < 0 ? -1 : 1),
|
||||
&GRAPHENE_POINT_INIT (scale_x < 0 ? - (node->bounds.size.width + 2 * node->bounds.origin.x) : 0,
|
||||
scale_y < 0 ? - (node->bounds.size.height + 2 * node->bounds.origin.y) : 0));
|
||||
gsk_gl_render_job_push_modelview (job, transform);
|
||||
gsk_transform_unref (transform);
|
||||
}
|
||||
@@ -2966,10 +2939,10 @@ compute_phase_and_pos (float value, float *pos)
|
||||
}
|
||||
|
||||
static inline void
|
||||
gsk_gl_render_job_visit_text_node_legacy (GskGLRenderJob *job,
|
||||
const GskRenderNode *node,
|
||||
const GdkRGBA *color,
|
||||
gboolean force_color)
|
||||
gsk_gl_render_job_visit_text_node (GskGLRenderJob *job,
|
||||
const GskRenderNode *node,
|
||||
const GdkRGBA *color,
|
||||
gboolean force_color)
|
||||
{
|
||||
const PangoFont *font = gsk_text_node_get_font (node);
|
||||
const PangoGlyphInfo *glyphs = gsk_text_node_get_glyphs (node, NULL);
|
||||
@@ -3105,263 +3078,6 @@ gsk_gl_render_job_visit_text_node_legacy (GskGLRenderJob *job,
|
||||
}
|
||||
}
|
||||
|
||||
/* Keep this in sync with glyph_vertex_transcode in glyphy.vs.glsl */
|
||||
typedef struct
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float g16hi;
|
||||
float g16lo;
|
||||
} EncodedGlyph;
|
||||
|
||||
static inline unsigned int
|
||||
glyph_encode (guint atlas_x , /* 7 bits */
|
||||
guint atlas_y, /* 7 bits */
|
||||
guint corner_x, /* 1 bit */
|
||||
guint corner_y, /* 1 bit */
|
||||
guint nominal_w, /* 6 bits */
|
||||
guint nominal_h) /* 6 bits */
|
||||
{
|
||||
guint x, y;
|
||||
|
||||
g_assert (0 == (atlas_x & ~0x7F));
|
||||
g_assert (0 == (atlas_y & ~0x7F));
|
||||
g_assert (0 == (corner_x & ~1));
|
||||
g_assert (0 == (corner_y & ~1));
|
||||
g_assert (0 == (nominal_w & ~0x3F));
|
||||
g_assert (0 == (nominal_h & ~0x3F));
|
||||
|
||||
x = (((atlas_x << 6) | nominal_w) << 1) | corner_x;
|
||||
y = (((atlas_y << 6) | nominal_h) << 1) | corner_y;
|
||||
|
||||
return (x << 16) | y;
|
||||
}
|
||||
|
||||
static inline void
|
||||
encoded_glyph_init (EncodedGlyph *eg,
|
||||
float x,
|
||||
float y,
|
||||
guint corner_x,
|
||||
guint corner_y,
|
||||
const GskGLGlyphyValue *gi)
|
||||
{
|
||||
guint encoded = glyph_encode (gi->atlas_x, gi->atlas_y, corner_x, corner_y, gi->nominal_w, gi->nominal_h);
|
||||
|
||||
eg->x = x;
|
||||
eg->y = y;
|
||||
eg->g16hi = encoded >> 16;
|
||||
eg->g16lo = encoded & 0xFFFF;
|
||||
}
|
||||
|
||||
static inline void
|
||||
add_encoded_glyph (GskGLDrawVertex *vertices,
|
||||
const EncodedGlyph *eg,
|
||||
const guint16 c[4])
|
||||
{
|
||||
*vertices = (GskGLDrawVertex) { .position = { eg->x, eg->y}, .uv = { eg->g16hi, eg->g16lo}, .color = { c[0], c[1], c[2], c[3] } };
|
||||
}
|
||||
|
||||
static void
|
||||
get_synthetic_font_params (PangoFont *font,
|
||||
gboolean *embolden,
|
||||
PangoMatrix *matrix)
|
||||
{
|
||||
*embolden = FALSE;
|
||||
*matrix = (PangoMatrix) PANGO_MATRIX_INIT;
|
||||
|
||||
#ifdef HAVE_PANGOFT
|
||||
if (PANGO_IS_FC_FONT (font))
|
||||
{
|
||||
FcPattern *pattern = pango_fc_font_get_pattern (PANGO_FC_FONT (font));
|
||||
FcBool b;
|
||||
FcMatrix mat;
|
||||
FcMatrix *m;
|
||||
|
||||
if (FcPatternGetBool (pattern, FC_EMBOLDEN, 0, &b) == FcResultMatch)
|
||||
*embolden = b;
|
||||
|
||||
FcMatrixInit (&mat);
|
||||
for (int i = 0; FcPatternGetMatrix (pattern, FC_MATRIX, i, &m) == FcResultMatch; i++)
|
||||
FcMatrixMultiply (&mat, &mat, m);
|
||||
|
||||
matrix->xx = mat.xx;
|
||||
matrix->xy = mat.xy;
|
||||
matrix->yx = mat.yx;
|
||||
matrix->yy = mat.yy;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
gsk_gl_render_job_visit_text_node_glyphy (GskGLRenderJob *job,
|
||||
const GskRenderNode *node,
|
||||
const GdkRGBA *color)
|
||||
{
|
||||
const graphene_point_t *offset;
|
||||
const PangoGlyphInfo *glyphs;
|
||||
const PangoGlyphInfo *gi;
|
||||
GskGLGlyphyLibrary *library;
|
||||
GskGLCommandBatch *batch;
|
||||
PangoFont *font;
|
||||
GskGLDrawVertex *vertices;
|
||||
const guint16 *c;
|
||||
GskGLGlyphyKey lookup;
|
||||
guint16 cc[4];
|
||||
float x;
|
||||
float y;
|
||||
guint last_texture = 0;
|
||||
guint num_glyphs;
|
||||
guint used = 0;
|
||||
guint i;
|
||||
int x_position = 0;
|
||||
float font_scale;
|
||||
gboolean embolden;
|
||||
PangoMatrix matrix = PANGO_MATRIX_INIT;
|
||||
|
||||
#define GRID_SIZE 20
|
||||
|
||||
g_assert (!gsk_text_node_has_color_glyphs (node));
|
||||
|
||||
if (!(num_glyphs = gsk_text_node_get_num_glyphs (node)))
|
||||
return;
|
||||
|
||||
if (RGBA_IS_CLEAR (color))
|
||||
return;
|
||||
|
||||
font = (PangoFont *)gsk_text_node_get_font (node);
|
||||
get_synthetic_font_params (font, &embolden, &matrix);
|
||||
|
||||
glyphs = gsk_text_node_get_glyphs (node, NULL);
|
||||
library = job->driver->glyphy_library;
|
||||
offset = gsk_text_node_get_offset (node);
|
||||
x = offset->x + job->offset_x;
|
||||
y = offset->y + job->offset_y;
|
||||
|
||||
rgba_to_half (color, cc);
|
||||
c = cc;
|
||||
|
||||
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, glyphy));
|
||||
|
||||
batch = gsk_gl_command_queue_get_batch (job->command_queue);
|
||||
vertices = gsk_gl_command_queue_add_n_vertices (job->command_queue, num_glyphs);
|
||||
|
||||
lookup.font = gsk_gl_glyphy_library_get_font_key (font);
|
||||
font_scale = gsk_gl_glyphy_library_get_font_scale (font);
|
||||
|
||||
for (i = 0, gi = glyphs; i < num_glyphs; i++, gi++)
|
||||
{
|
||||
const GskGLGlyphyValue *glyph;
|
||||
float cx = 0, cy = 0;
|
||||
guint texture_id;
|
||||
|
||||
lookup.glyph = gi->glyph;
|
||||
texture_id = gsk_gl_glyphy_library_lookup_or_add (library, &lookup, font, &glyph);
|
||||
|
||||
if G_UNLIKELY (texture_id == 0)
|
||||
continue;
|
||||
|
||||
if G_UNLIKELY (last_texture != texture_id || batch->draw.vbo_count + GSK_GL_N_VERTICES > 0xffff)
|
||||
{
|
||||
if G_LIKELY (last_texture != 0)
|
||||
{
|
||||
guint vbo_offset = batch->draw.vbo_offset + batch->draw.vbo_count;
|
||||
|
||||
/* Since we have batched added our VBO vertices to avoid repeated
|
||||
* calls to the buffer, we need to manually tweak the vbo offset
|
||||
* of the new batch as otherwise it will point at the end of our
|
||||
* vbo array.
|
||||
*/
|
||||
gsk_gl_render_job_split_draw (job);
|
||||
batch = gsk_gl_command_queue_get_batch (job->command_queue);
|
||||
batch->draw.vbo_offset = vbo_offset;
|
||||
}
|
||||
|
||||
gsk_gl_program_set_uniform4i (job->current_program,
|
||||
UNIFORM_GLYPHY_ATLAS_INFO, 0,
|
||||
GSK_GL_TEXTURE_LIBRARY (library)->atlas_width,
|
||||
GSK_GL_TEXTURE_LIBRARY (library)->atlas_height,
|
||||
library->item_w,
|
||||
library->item_h_q);
|
||||
gsk_gl_program_set_uniform_texture (job->current_program,
|
||||
UNIFORM_SHARED_SOURCE, 0,
|
||||
GL_TEXTURE_2D,
|
||||
GL_TEXTURE0,
|
||||
texture_id);
|
||||
gsk_gl_program_set_uniform1f (job->current_program,
|
||||
UNIFORM_GLYPHY_GAMMA_ADJUST, 0,
|
||||
1.0);
|
||||
gsk_gl_program_set_uniform1f (job->current_program,
|
||||
UNIFORM_GLYPHY_CONTRAST, 0,
|
||||
1.0);
|
||||
|
||||
/* 0.0208 is the value used by freetype for synthetic emboldening */
|
||||
gsk_gl_program_set_uniform1f (job->current_program,
|
||||
UNIFORM_GLYPHY_BOLDNESS, 0,
|
||||
embolden ? 0.0208 * GRID_SIZE : 0.0);
|
||||
|
||||
#if 0
|
||||
gsk_gl_program_set_uniform1f (job->current_program,
|
||||
UNIFORM_GLYPHY_OUTLINE_THICKNESS, 0,
|
||||
1.0);
|
||||
gsk_gl_program_set_uniform1f (job->current_program,
|
||||
UNIFORM_GLYPHY_OUTLINE, 0,
|
||||
1.0);
|
||||
#endif
|
||||
|
||||
last_texture = texture_id;
|
||||
}
|
||||
|
||||
cx = (float)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
|
||||
if G_UNLIKELY (gi->geometry.y_offset != 0)
|
||||
cy = (float)(gi->geometry.y_offset) / PANGO_SCALE;
|
||||
|
||||
x_position += gi->geometry.width;
|
||||
|
||||
EncodedGlyph encoded[4];
|
||||
#define ENCODE_CORNER(_cx, _cy) \
|
||||
G_STMT_START { \
|
||||
float _dx = _cx * (glyph->extents.max_x - glyph->extents.min_x); \
|
||||
float _dy = _cy * (glyph->extents.max_y - glyph->extents.min_y); \
|
||||
float _vx = x + cx + font_scale * (glyph->extents.min_x + matrix.xx * _dx + matrix.xy * _dy); \
|
||||
float _vy = y + cy - font_scale * (glyph->extents.min_y + matrix.yx * _dx + matrix.yy * _dy); \
|
||||
encoded_glyph_init (&encoded[_cx * 2 + _cy], _vx, _vy, _cx, _cy, glyph); \
|
||||
} G_STMT_END
|
||||
ENCODE_CORNER (0, 0);
|
||||
ENCODE_CORNER (0, 1);
|
||||
ENCODE_CORNER (1, 0);
|
||||
ENCODE_CORNER (1, 1);
|
||||
#undef ENCODE_CORNER
|
||||
|
||||
add_encoded_glyph (vertices++, &encoded[0], c);
|
||||
add_encoded_glyph (vertices++, &encoded[1], c);
|
||||
add_encoded_glyph (vertices++, &encoded[2], c);
|
||||
|
||||
add_encoded_glyph (vertices++, &encoded[1], c);
|
||||
add_encoded_glyph (vertices++, &encoded[2], c);
|
||||
add_encoded_glyph (vertices++, &encoded[3], c);
|
||||
|
||||
batch->draw.vbo_count += GSK_GL_N_VERTICES;
|
||||
used++;
|
||||
}
|
||||
|
||||
if (used != num_glyphs)
|
||||
gsk_gl_command_queue_retract_n_vertices (job->command_queue, num_glyphs - used);
|
||||
|
||||
gsk_gl_render_job_end_draw (job);
|
||||
}
|
||||
|
||||
static inline void
|
||||
gsk_gl_render_job_visit_text_node (GskGLRenderJob *job,
|
||||
const GskRenderNode *node,
|
||||
const GdkRGBA *color,
|
||||
gboolean force_color)
|
||||
{
|
||||
if (job->use_glyphy && !gsk_text_node_has_color_glyphs (node))
|
||||
gsk_gl_render_job_visit_text_node_glyphy (job, node, color);
|
||||
else
|
||||
gsk_gl_render_job_visit_text_node_legacy (job, node, color, force_color);
|
||||
}
|
||||
|
||||
static inline void
|
||||
gsk_gl_render_job_visit_shadow_node (GskGLRenderJob *job,
|
||||
const GskRenderNode *node)
|
||||
@@ -4075,7 +3791,7 @@ gsk_gl_render_job_visit_texture_scale_node (GskGLRenderJob *job,
|
||||
slice_bounds.size.width = slice->rect.width * scale_x;
|
||||
slice_bounds.size.height = slice->rect.height * scale_y;
|
||||
|
||||
if (!graphene_rect_intersection (&slice_bounds, &viewport, NULL))
|
||||
if (!gsk_rect_intersects (&slice_bounds, &viewport))
|
||||
continue;
|
||||
|
||||
if (i > 0)
|
||||
@@ -4153,7 +3869,7 @@ gsk_gl_render_job_visit_repeat_node (GskGLRenderJob *job,
|
||||
/* If the size of the repeat node is smaller than the size of the
|
||||
* child node, we don't repeat at all and can just draw that part
|
||||
* of the child texture... */
|
||||
if (rect_contains_rect (child_bounds, &node->bounds))
|
||||
if (gsk_rect_contains_rect (child_bounds, &node->bounds))
|
||||
{
|
||||
gsk_gl_render_job_visit_clipped_child (job, child, &node->bounds);
|
||||
return;
|
||||
@@ -4377,6 +4093,14 @@ gsk_gl_render_job_visit_node (GskGLRenderJob *job,
|
||||
gsk_gl_render_job_visit_as_fallback (job, node);
|
||||
break;
|
||||
|
||||
case GSK_FILL_NODE:
|
||||
gsk_gl_render_job_visit_as_fallback (job, node);
|
||||
break;
|
||||
|
||||
case GSK_STROKE_NODE:
|
||||
gsk_gl_render_job_visit_as_fallback (job, node);
|
||||
break;
|
||||
|
||||
case GSK_NOT_A_RENDER_NODE:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
@@ -4727,15 +4451,6 @@ gsk_gl_render_job_set_debug_fallback (GskGLRenderJob *job,
|
||||
job->debug_fallback = !!debug_fallback;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gl_render_job_set_use_glyphy (GskGLRenderJob *job,
|
||||
gboolean use_glyphy)
|
||||
{
|
||||
g_return_if_fail (job != NULL);
|
||||
|
||||
job->use_glyphy = !!use_glyphy;
|
||||
}
|
||||
|
||||
static int
|
||||
get_framebuffer_format (GdkGLContext *context,
|
||||
guint framebuffer)
|
||||
|
||||
@@ -35,5 +35,4 @@ void gsk_gl_render_job_render_flipped (GskGLRenderJob *job
|
||||
GskRenderNode *root);
|
||||
void gsk_gl_render_job_set_debug_fallback (GskGLRenderJob *job,
|
||||
gboolean debug_fallback);
|
||||
void gsk_gl_render_job_set_use_glyphy (GskGLRenderJob *job,
|
||||
gboolean use_glyphy);
|
||||
|
||||
|
||||
@@ -36,14 +36,9 @@ G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GskGLTextureAtlas
|
||||
{
|
||||
/* Used by Glyph/Icons */
|
||||
struct stbrp_context context;
|
||||
struct stbrp_node *nodes;
|
||||
|
||||
/* Used by Glyphy */
|
||||
int cursor_x;
|
||||
int cursor_y;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
@@ -53,6 +48,7 @@ typedef struct _GskGLTextureAtlas
|
||||
* But are now unused.
|
||||
*/
|
||||
int unused_pixels;
|
||||
|
||||
} GskGLTextureAtlas;
|
||||
|
||||
typedef struct _GskGLTextureAtlasEntry
|
||||
|
||||
@@ -36,7 +36,6 @@ typedef struct _GskGLCompiler GskGLCompiler;
|
||||
typedef struct _GskGLDrawVertex GskGLDrawVertex;
|
||||
typedef struct _GskGLRenderTarget GskGLRenderTarget;
|
||||
typedef struct _GskGLGlyphLibrary GskGLGlyphLibrary;
|
||||
typedef struct _GskGLGlyphyLibrary GskGLGlyphyLibrary;
|
||||
typedef struct _GskGLIconLibrary GskGLIconLibrary;
|
||||
typedef struct _GskGLProgram GskGLProgram;
|
||||
typedef struct _GskGLRenderJob GskGLRenderJob;
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
uniform ivec4 u_atlas_info;
|
||||
|
||||
#define GLYPHY_TEXTURE1D_EXTRA_DECLS , sampler2D _tex, ivec4 _atlas_info, ivec2 _atlas_pos
|
||||
#define GLYPHY_TEXTURE1D_EXTRA_ARGS , _tex, _atlas_info, _atlas_pos
|
||||
#define GLYPHY_DEMO_EXTRA_ARGS , u_source, u_atlas_info, gi.atlas_pos
|
||||
|
||||
vec4
|
||||
glyphy_texture1D_func (int offset GLYPHY_TEXTURE1D_EXTRA_DECLS)
|
||||
{
|
||||
ivec2 item_geom = _atlas_info.zw;
|
||||
vec2 pos = (vec2 (_atlas_pos.xy * item_geom +
|
||||
ivec2 (mod (float (offset), float (item_geom.x)), offset / item_geom.x)) +
|
||||
+ vec2 (.5, .5)) / vec2(_atlas_info.xy);
|
||||
return GskTexture (_tex, pos);
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
// FRAGMENT_SHADER:
|
||||
// glyphy.fs.glsl
|
||||
|
||||
uniform float u_contrast;
|
||||
uniform float u_gamma_adjust;
|
||||
uniform float u_outline_thickness;
|
||||
uniform bool u_outline;
|
||||
uniform float u_boldness;
|
||||
|
||||
_IN_ vec4 v_glyph;
|
||||
_IN_ vec4 final_color;
|
||||
|
||||
#define SQRT2 1.4142135623730951
|
||||
#define SQRT2_INV 0.70710678118654757 /* 1 / sqrt(2.) */
|
||||
|
||||
struct glyph_info_t {
|
||||
ivec2 nominal_size;
|
||||
ivec2 atlas_pos;
|
||||
};
|
||||
|
||||
glyph_info_t
|
||||
glyph_info_decode (vec4 v)
|
||||
{
|
||||
glyph_info_t gi;
|
||||
gi.nominal_size = (ivec2 (mod (v.zw, 256.)) + 2) / 4;
|
||||
gi.atlas_pos = ivec2 (v_glyph.zw) / 256;
|
||||
return gi;
|
||||
}
|
||||
|
||||
float
|
||||
antialias (float d)
|
||||
{
|
||||
return smoothstep (-.75, +.75, d);
|
||||
}
|
||||
|
||||
void
|
||||
main()
|
||||
{
|
||||
vec2 p = v_glyph.xy;
|
||||
glyph_info_t gi = glyph_info_decode (v_glyph);
|
||||
|
||||
/* isotropic antialiasing */
|
||||
vec2 dpdx = dFdx (p);
|
||||
vec2 dpdy = dFdy (p);
|
||||
float m = length (vec2 (length (dpdx), length (dpdy))) * SQRT2_INV;
|
||||
|
||||
float gsdist = glyphy_sdf (p, gi.nominal_size GLYPHY_DEMO_EXTRA_ARGS);
|
||||
gsdist -= u_boldness;
|
||||
float sdist = gsdist / m * u_contrast;
|
||||
|
||||
if (u_outline)
|
||||
sdist = abs (sdist) - u_outline_thickness * .5;
|
||||
|
||||
if (sdist > 1.)
|
||||
discard;
|
||||
|
||||
float alpha = antialias (-sdist);
|
||||
if (u_gamma_adjust != 1.)
|
||||
alpha = pow (alpha, 1./u_gamma_adjust);
|
||||
|
||||
gskSetOutputColor(final_color * alpha);
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
// VERTEX_SHADER:
|
||||
// glyphy.vs.glsl
|
||||
|
||||
_OUT_ vec4 v_glyph;
|
||||
_OUT_ vec4 final_color;
|
||||
|
||||
// Keep this in sync with glyph_encode in gskglrenderjob.c
|
||||
vec4
|
||||
glyph_vertex_transcode (vec2 v)
|
||||
{
|
||||
ivec2 g = ivec2 (v);
|
||||
ivec2 corner = ivec2 (mod (v, 2.));
|
||||
g /= 2;
|
||||
ivec2 nominal_size = ivec2 (mod (vec2(g), 64.));
|
||||
return vec4 (corner * nominal_size, g * 4);
|
||||
}
|
||||
|
||||
void
|
||||
main()
|
||||
{
|
||||
v_glyph = glyph_vertex_transcode(aUv);
|
||||
vUv = v_glyph.zw;
|
||||
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
||||
final_color = gsk_scaled_premultiply(aColor, u_alpha);
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
#extension GL_OES_standard_derivatives : enable
|
||||
|
||||
#ifndef GSK_LEGACY
|
||||
precision highp float;
|
||||
#endif
|
||||
|
||||
@@ -20,9 +20,14 @@
|
||||
#define __GSK_H_INSIDE__
|
||||
|
||||
#include <gsk/gskenums.h>
|
||||
#include <gsk/gskpath.h>
|
||||
#include <gsk/gskpathbuilder.h>
|
||||
#include <gsk/gskpathmeasure.h>
|
||||
#include <gsk/gskpathpoint.h>
|
||||
#include <gsk/gskrenderer.h>
|
||||
#include <gsk/gskrendernode.h>
|
||||
#include <gsk/gskroundedrect.h>
|
||||
#include <gsk/gskstroke.h>
|
||||
#include <gsk/gsktransform.h>
|
||||
#include <gsk/gskglshader.h>
|
||||
|
||||
|
||||
@@ -97,4 +97,19 @@ gsk_bounding_box_intersection (const GskBoundingBox *a,
|
||||
return min.x <= max.x && min.y <= max.y;
|
||||
}
|
||||
|
||||
static inline void
|
||||
gsk_bounding_box_union (const GskBoundingBox *a,
|
||||
const GskBoundingBox *b,
|
||||
GskBoundingBox *res)
|
||||
{
|
||||
graphene_point_t min, max;
|
||||
|
||||
min.x = MIN (a->min.x, b->min.x);
|
||||
min.y = MIN (a->min.y, b->min.y);
|
||||
max.x = MAX (a->max.x, b->max.x);
|
||||
max.y = MAX (a->max.y, b->max.y);
|
||||
|
||||
gsk_bounding_box_init (res, &min, &max);
|
||||
}
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user