Compare commits
308 Commits
simple-lab
...
pango2-win
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
24d25b0db5 | ||
|
|
30147b1a99 | ||
|
|
3979def662 | ||
|
|
71ea2e2ecb | ||
|
|
c79b4e2e56 | ||
|
|
f7c4b26c59 | ||
|
|
a13cfde2a9 | ||
|
|
3a5d161b8a | ||
|
|
baabb57df3 | ||
|
|
a69d39d945 | ||
|
|
646149bc72 | ||
|
|
b01eb0600c | ||
|
|
5b92bf51a0 | ||
|
|
8ab180b3a9 | ||
|
|
897195b2f5 | ||
|
|
d595cc1c55 | ||
|
|
2841256260 | ||
|
|
ff0fec0f7d | ||
|
|
d0894b2786 | ||
|
|
5ba8fc8f10 | ||
|
|
5d05daaed0 | ||
|
|
86dd72fad6 | ||
|
|
b0766a62ec | ||
|
|
a664d06c2f | ||
|
|
d42c51e27d | ||
|
|
63af01f7c9 | ||
|
|
12f7929f44 | ||
|
|
9c4490b7ad | ||
|
|
f0d329cf5e | ||
|
|
58d79e87ea | ||
|
|
cd40cd145f | ||
|
|
4f6b5b0fac | ||
|
|
88bbb933a1 | ||
|
|
4070e794d2 | ||
|
|
3b6ec027d3 | ||
|
|
a284dc9f31 | ||
|
|
091daf4cff | ||
|
|
64f3ac6760 | ||
|
|
508ceccb66 | ||
|
|
d6dde63074 | ||
|
|
bdb1886fc9 | ||
|
|
faa9ef2dc0 | ||
|
|
21b9667f08 | ||
|
|
e4781e393c | ||
|
|
7536513ef8 | ||
|
|
6776c21350 | ||
|
|
9f4ef77663 | ||
|
|
a64bb67ef7 | ||
|
|
53f3b4b9d9 | ||
|
|
5bb4d69720 | ||
|
|
35808a918d | ||
|
|
672618e560 | ||
|
|
e28516d189 | ||
|
|
dfe9460240 | ||
|
|
01820d8524 | ||
|
|
be1729b316 | ||
|
|
57f2b5d2e6 | ||
|
|
c00b234440 | ||
|
|
8d803e8615 | ||
|
|
9477ecbc92 | ||
|
|
1e686ee535 | ||
|
|
4d883861b1 | ||
|
|
f9c0fc4fdd | ||
|
|
354f1a783a | ||
|
|
813dd0a674 | ||
|
|
bbfacb4d22 | ||
|
|
086f2324a3 | ||
|
|
c378eacb5d | ||
|
|
0660bb834e | ||
|
|
092fe2f712 | ||
|
|
5be54fad82 | ||
|
|
d91e669d98 | ||
|
|
9a22577e34 | ||
|
|
88366c5e13 | ||
|
|
287ed99130 | ||
|
|
40e09cf2bb | ||
|
|
5a3ca064ea | ||
|
|
edc991dafd | ||
|
|
a1d03e69a4 | ||
|
|
18c2ba9b71 | ||
|
|
3da3cb35a6 | ||
|
|
e54567611b | ||
|
|
ce88d19015 | ||
|
|
5301a74bd3 | ||
|
|
381c34783d | ||
|
|
3ea8dc02a3 | ||
|
|
83c780cfad | ||
|
|
4b5d218067 | ||
|
|
8944493eca | ||
|
|
dd9f26c492 | ||
|
|
3c038dc239 | ||
|
|
9ee555719e | ||
|
|
7953092059 | ||
|
|
de1a8c8d89 | ||
|
|
98e000beb7 | ||
|
|
8b3a38779b | ||
|
|
8d72c8ee5f | ||
|
|
f9b0866415 | ||
|
|
dbe06357ec | ||
|
|
9e03c3f6cd | ||
|
|
2d14372142 | ||
|
|
0a4c08a7be | ||
|
|
883011f252 | ||
|
|
4927b6e625 | ||
|
|
c93a01d627 | ||
|
|
221a18704b | ||
|
|
62984d091a | ||
|
|
6d15549f51 | ||
|
|
4c1fc4f5d7 | ||
|
|
98e0ca7477 | ||
|
|
4809efd630 | ||
|
|
d88e935398 | ||
|
|
393ef4d0a2 | ||
|
|
efd9aac3fa | ||
|
|
c7c8b37e4c | ||
|
|
11aef91fa5 | ||
|
|
f48c9b8388 | ||
|
|
62096ebd16 | ||
|
|
f7b8184b00 | ||
|
|
b91f60b4f9 | ||
|
|
b6ba8ecbd0 | ||
|
|
02ee10639d | ||
|
|
0e42fa95b1 | ||
|
|
7a36632afc | ||
|
|
301f1a577d | ||
|
|
67e336992f | ||
|
|
e1845f5e90 | ||
|
|
d7dae84af2 | ||
|
|
0f829c4599 | ||
|
|
3fca865625 | ||
|
|
bf8b26aa27 | ||
|
|
cbc3d3f3ec | ||
|
|
fd4562aac9 | ||
|
|
c26962c4b1 | ||
|
|
46ce19d22a | ||
|
|
303bc3bb1b | ||
|
|
bf5edc6b7c | ||
|
|
7c034cc283 | ||
|
|
e437a9c348 | ||
|
|
1517c1813c | ||
|
|
9973a7173f | ||
|
|
01fcfc5c2a | ||
|
|
3f4c88aad1 | ||
|
|
8a0d6da187 | ||
|
|
b8199bcc1f | ||
|
|
abdbef1b5e | ||
|
|
6ac7f0562b | ||
|
|
c796b30136 | ||
|
|
61bc38cd61 | ||
|
|
b56b5ed81b | ||
|
|
b6a8080b2f | ||
|
|
0400607102 | ||
|
|
5089fa3ecc | ||
|
|
dec6a93510 | ||
|
|
27db4b5c2f | ||
|
|
c3706ea9ec | ||
|
|
e4869938b7 | ||
|
|
fa1dca29b6 | ||
|
|
5abaee4f02 | ||
|
|
d2b6fef1f8 | ||
|
|
9de027df65 | ||
|
|
a639aaefae | ||
|
|
39645d3258 | ||
|
|
526b62e0be | ||
|
|
19fb336c39 | ||
|
|
1f3674cf3e | ||
|
|
c76069389c | ||
|
|
eef0c81be9 | ||
|
|
c78eeaa874 | ||
|
|
2766f61abc | ||
|
|
45422f7b61 | ||
|
|
c4feca1311 | ||
|
|
9426b20759 | ||
|
|
f97cff1454 | ||
|
|
549a2b4c86 | ||
|
|
f4f0daa113 | ||
|
|
d4f8a80f2a | ||
|
|
8d175801d7 | ||
|
|
6bc3ecbe56 | ||
|
|
dc4540fae9 | ||
|
|
31da5f7e2a | ||
|
|
48228efe42 | ||
|
|
4b41d4f78c | ||
|
|
fb68600d88 | ||
|
|
0e6a3ab397 | ||
|
|
e895f7dd70 | ||
|
|
dae892d8f6 | ||
|
|
ad5c3168a9 | ||
|
|
8f1db27b6b | ||
|
|
56a1cbe217 | ||
|
|
63e9e7e899 | ||
|
|
480a933546 | ||
|
|
2623c396cb | ||
|
|
826fdc4a80 | ||
|
|
3b088281ca | ||
|
|
e61aecd67e | ||
|
|
bd68339390 | ||
|
|
491d1f67c7 | ||
|
|
73dc741a82 | ||
|
|
38ec040fce | ||
|
|
6bb1873183 | ||
|
|
5ba5693efd | ||
|
|
797cc2e91b | ||
|
|
5507b3f8c1 | ||
|
|
f9a3f13702 | ||
|
|
b4c72ac508 | ||
|
|
bcad305136 | ||
|
|
00d45c6743 | ||
|
|
38b393ff5d | ||
|
|
23f92ca1c2 | ||
|
|
34a9bc4632 | ||
|
|
d603164ec2 | ||
|
|
a033e838b2 | ||
|
|
511a2f4d03 | ||
|
|
c089912a52 | ||
|
|
2694d81d63 | ||
|
|
213490099b | ||
|
|
166af48904 | ||
|
|
6e3dbc42a8 | ||
|
|
36fbbfc5c7 | ||
|
|
9bfc89e23d | ||
|
|
802bf41999 | ||
|
|
93636d4c5a | ||
|
|
88f761f2c8 | ||
|
|
7752467847 | ||
|
|
8514457d0f | ||
|
|
c0d79aa1ef | ||
|
|
8a6d6fe6b1 | ||
|
|
7750a2c423 | ||
|
|
393893b8db | ||
|
|
4f16242807 | ||
|
|
e82fb8e894 | ||
|
|
b3e65bfdc1 | ||
|
|
111daecd3b | ||
|
|
72fe406c4d | ||
|
|
0f01629ce3 | ||
|
|
2f695388e9 | ||
|
|
3955633aa8 | ||
|
|
f77f941401 | ||
|
|
288dd406e0 | ||
|
|
8667b7a46c | ||
|
|
0410125f20 | ||
|
|
1ea0de61e1 | ||
|
|
e8eb96ae0c | ||
|
|
04f924c13e | ||
|
|
1fbca7a76a | ||
|
|
3f49d335d1 | ||
|
|
3882e14053 | ||
|
|
5f5fda911d | ||
|
|
b9574e119b | ||
|
|
5f469a0d2d | ||
|
|
ffd3801b1d | ||
|
|
fd21df7244 | ||
|
|
654d74bfb8 | ||
|
|
a26c72ef79 | ||
|
|
6b55a14429 | ||
|
|
bc241d62af | ||
|
|
2b2894490f | ||
|
|
c0747f2c2e | ||
|
|
b34beb9380 | ||
|
|
8f19099f1a | ||
|
|
db2516af0a | ||
|
|
bd07f846ef | ||
|
|
d938352fb3 | ||
|
|
13eef432fc | ||
|
|
1b355ff2e0 | ||
|
|
aa9a8702e4 | ||
|
|
ab2109ea6b | ||
|
|
926eb161f8 | ||
|
|
61bb9bb935 | ||
|
|
8f55a014b1 | ||
|
|
c3e5d80853 | ||
|
|
8bd77441a9 | ||
|
|
a2af794cb0 | ||
|
|
0c86b28828 | ||
|
|
4278e91a46 | ||
|
|
dd16d7c4c8 | ||
|
|
6164908bd3 | ||
|
|
2ff98dad03 | ||
|
|
f33c521836 | ||
|
|
e1159dab93 | ||
|
|
c4f423694f | ||
|
|
4f2b1b3cfc | ||
|
|
122fa679a8 | ||
|
|
7302407880 | ||
|
|
900a23e2bb | ||
|
|
0f7d93492d | ||
|
|
aee4475c0f | ||
|
|
1f61cb2251 | ||
|
|
0382e3b46c | ||
|
|
547b2891cb | ||
|
|
89614f5f72 | ||
|
|
f5fc71fe82 | ||
|
|
a546ae32d7 | ||
|
|
17578a97d6 | ||
|
|
9536eb654b | ||
|
|
0f21f6c273 | ||
|
|
4bf07aeef9 | ||
|
|
26b250503d | ||
|
|
8533824084 | ||
|
|
5a0d6e3fc8 | ||
|
|
6be466b675 | ||
|
|
1c587c7d7f | ||
|
|
2f98de06bc | ||
|
|
9e6855cdb8 | ||
|
|
a6c3e440f6 | ||
|
|
08d386844a | ||
|
|
48e98d333e |
@@ -25,7 +25,7 @@ variables:
|
||||
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
|
||||
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled"
|
||||
MESON_TEST_TIMEOUT_MULTIPLIER: 3
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v36"
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v38"
|
||||
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
|
||||
|
||||
.only-default:
|
||||
@@ -58,6 +58,7 @@ style-check-diff:
|
||||
- "${CI_PROJECT_DIR}/_build/report*.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report*.html"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/reftests/output/*/*.png"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/reftests/output/*/*.node"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/tools/output/*/*"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/gsk/compare/*/*/*.png"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/css/output/*/*.syscap"
|
||||
@@ -172,7 +173,7 @@ macos:
|
||||
needs: []
|
||||
before_script:
|
||||
- bash .gitlab-ci/show-info-osx.sh
|
||||
- pip3 install --user meson==0.59
|
||||
- pip3 install --user meson==0.60.3
|
||||
- pip3 install --user ninja
|
||||
- export PATH=/Users/gitlabrunner/Library/Python/3.7/bin:$PATH
|
||||
- export MESON_FORCE_BACKTRACE=1
|
||||
@@ -345,6 +346,7 @@ reference:
|
||||
- _reference
|
||||
|
||||
publish-docs:
|
||||
image: fedora:latest
|
||||
stage: publish
|
||||
needs: ['reference']
|
||||
script:
|
||||
|
||||
@@ -14,6 +14,9 @@ Each Docker image has a tag composed of two parts:
|
||||
See the [container registry][registry] for the available images for each
|
||||
branch, as well as their available versions.
|
||||
|
||||
Note that using `latest` as version number will overwrite the most
|
||||
recently uploaded image in the registry.
|
||||
|
||||
### Checklist for Updating a CI image
|
||||
|
||||
- [ ] Update the `${image}.Dockerfile` file with the dependencies
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM fedora:34
|
||||
FROM fedora:36
|
||||
|
||||
RUN dnf -y install \
|
||||
adwaita-icon-theme \
|
||||
@@ -87,7 +87,6 @@ RUN dnf -y install \
|
||||
python3-wheel \
|
||||
redhat-rpm-config \
|
||||
sassc \
|
||||
systemtap-sdt-devel \
|
||||
vulkan-devel \
|
||||
wayland-devel \
|
||||
wayland-protocols-devel \
|
||||
|
||||
@@ -185,6 +185,8 @@ ul.images li {
|
||||
<li><img alt="ref" src="{{ failure.image_data.ref }}" /></li>
|
||||
<li><img alt="out" src="{{ failure.image_data.out }}" /></li>
|
||||
<li><img alt="diff" src="{{ failure.image_data.diff }}" /></li>
|
||||
<li><a href="{{ failure.image_data.refnode }}">ref node</a></li>
|
||||
<li><a href="{{ failure.image_data.outnode }}">out node</a></li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
</li>
|
||||
@@ -311,6 +313,8 @@ for line in args.infile:
|
||||
image_data = {
|
||||
'ref': os.path.join(args.reftest_output_dir, '{}.ref.png'.format(basename)),
|
||||
'out': os.path.join(args.reftest_output_dir, '{}.out.png'.format(basename)),
|
||||
'refnode': os.path.join(args.reftest_output_dir, '{}.ref.node'.format(basename)),
|
||||
'outnode': os.path.join(args.reftest_output_dir, '{}.out.node'.format(basename)),
|
||||
'diff': os.path.join(args.reftest_output_dir, '{}.diff.png'.format(basename)),
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliar
|
||||
@echo on
|
||||
|
||||
:: FIXME: make warnings fatal
|
||||
pip3 install --upgrade --user meson==0.59 || goto :error
|
||||
pip3 install --upgrade --user meson==0.60.3 || goto :error
|
||||
meson -Ddebug=false -Dmedia-gstreamer=disabled _build || goto :error
|
||||
ninja -C _build || goto :error
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ pacman --noconfirm -S --needed \
|
||||
mingw-w64-$MSYS2_ARCH-graphene \
|
||||
mingw-w64-$MSYS2_ARCH-json-glib \
|
||||
mingw-w64-$MSYS2_ARCH-libepoxy \
|
||||
mingw-w64-$MSYS2_ARCH-pango \
|
||||
mingw-w64-$MSYS2_ARCH-pango2 \
|
||||
mingw-w64-$MSYS2_ARCH-fribidi \
|
||||
mingw-w64-$MSYS2_ARCH-gst-plugins-bad-libs \
|
||||
mingw-w64-$MSYS2_ARCH-shared-mime-info \
|
||||
|
||||
150
NEWS
150
NEWS
@@ -1,3 +1,153 @@
|
||||
Overview of Changes in 4.7.0, 07-05-2022
|
||||
========================================
|
||||
|
||||
* GtkTextView:
|
||||
- Reduce overdraws
|
||||
|
||||
* GtkViewport:
|
||||
- Default scroll-to-focus to TRUE
|
||||
|
||||
* GtkText:
|
||||
- Stop blinking when we lose focus
|
||||
|
||||
* GtkSearchEntry:
|
||||
- Make search delay configurable
|
||||
|
||||
* GtkPopoverMenu:
|
||||
- Fix RTL positioning of buttons
|
||||
|
||||
* GtkLabel:
|
||||
- Fix focus keynav with links
|
||||
|
||||
* GtkFileChooser:
|
||||
- Prevent undesirable completion popups
|
||||
- Fix a corner case in save mode
|
||||
- Keep the portal filechooser alive long enough
|
||||
|
||||
* GtkCheckButton:
|
||||
- Allow setting a custom child
|
||||
|
||||
* GtkEditableLabel:
|
||||
- Make the :editing property writable
|
||||
|
||||
* GtkColumnView:
|
||||
- Various optimizations to improve scrolling performance
|
||||
|
||||
* GtkTreeStore:
|
||||
- Allow populating tree stores from ui files
|
||||
|
||||
* GtkBoxLayout:
|
||||
- Avoid infinite loops
|
||||
|
||||
* CSS:
|
||||
- Optimize reordering within the same parent
|
||||
|
||||
* Emoji:
|
||||
- Update to CLDR v40 / Unicode 14
|
||||
- Add more locales
|
||||
|
||||
* Input:
|
||||
- Add scroll unit handling
|
||||
- Handle display changes in GtkIMMultiContext
|
||||
- Always populate GDK_AXIS_X/Y in event history
|
||||
- Don't crash for large compose tables
|
||||
|
||||
* Accessibility:
|
||||
- Fix a crash at start when orca is running
|
||||
|
||||
* Theme:
|
||||
- Refresh icons
|
||||
- Fix selection in vertical spin buttons
|
||||
- Fix selection in editable labels
|
||||
|
||||
* gdk:
|
||||
- Optimize pixel format conversions
|
||||
- Use EGL_KHR_swap_buffers_with_damage for NVidia
|
||||
|
||||
* gsk:
|
||||
- Handle large viewports
|
||||
- Prepare texture libraries for glyphy rendering
|
||||
- Don't leak big glyphs in the glyph cache
|
||||
- Align offscreen rendering with th pixel grid
|
||||
- Check for half-float support before using it
|
||||
|
||||
* Wayland:
|
||||
- Use xdg-activation protocol
|
||||
- Fix text caret coordinates
|
||||
- Fix on-screen keyboard activation
|
||||
|
||||
* MacOS:
|
||||
- Fix sluggish and reversed scrolling
|
||||
- Improve monitor detection
|
||||
- Event handling fixes
|
||||
- Fix keyboard input on popovers
|
||||
- Support OpenGL-based video playback
|
||||
- Suport fullscreen
|
||||
- Improve native filechoooser size allocation
|
||||
- Use CALayer and IOSurface for rendering
|
||||
- Use a per-monitor CVDisplayLink
|
||||
- Fix kinetic scrolling
|
||||
- Improve window placement
|
||||
- Improve multi-monitor handling
|
||||
- Start applications in the foreground
|
||||
- Fix cursor blink time
|
||||
|
||||
* Windows:
|
||||
- Fix preedit window placement on HiDPI
|
||||
|
||||
* Tools:
|
||||
- gtk4-builder-tool: Don't require a display for all commands
|
||||
- gtk4-builder-tool: Add a screenshot command
|
||||
- gtk4-node-editor: Install this utility
|
||||
|
||||
* Debugging:
|
||||
- inspector: Show more application data
|
||||
- inspector: Allow viewing PangoAttrList properties
|
||||
|
||||
* Documentation:
|
||||
- Use the gtk-builder-tool to generate screenshots
|
||||
|
||||
* Build:
|
||||
- Fix cross-compilation
|
||||
- Fix build on aarch64
|
||||
- Fix build with gcc 12
|
||||
|
||||
* Translation updates
|
||||
Basque
|
||||
Brazilian Portuguese
|
||||
British English
|
||||
Catalan
|
||||
Chinese (China)
|
||||
Chinese (Taiwan)
|
||||
Croatian
|
||||
Czech
|
||||
Danish
|
||||
Finnish
|
||||
Galician
|
||||
Georgian
|
||||
German
|
||||
Hebrew
|
||||
Hungarian
|
||||
Indonesian
|
||||
Italian
|
||||
Kazakh
|
||||
Korean
|
||||
Latvian
|
||||
Lithuanian
|
||||
Norwegian Bokmål
|
||||
Persian
|
||||
Polish
|
||||
Portuguese
|
||||
Russian
|
||||
Serbian
|
||||
Slovak
|
||||
Slovenian
|
||||
Spanish
|
||||
Swedish
|
||||
Turkish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.6.1, 11-02-2022
|
||||
========================================
|
||||
|
||||
|
||||
1959
demos/font-explorer/font_features.c
Normal file
1959
demos/font-explorer/font_features.c
Normal file
File diff suppressed because it is too large
Load Diff
287
demos/font-explorer/fontcolors.c
Normal file
287
demos/font-explorer/fontcolors.c
Normal file
@@ -0,0 +1,287 @@
|
||||
#include "fontcolors.h"
|
||||
#include "rangeedit.h"
|
||||
#include <gtk/gtk.h>
|
||||
#include <hb-ot.h>
|
||||
|
||||
enum {
|
||||
PROP_FONT_DESC = 1,
|
||||
PROP_PALETTE,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
struct _FontColors
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
GtkGrid *label;
|
||||
GtkGrid *grid;
|
||||
Pango2FontDescription *font_desc;
|
||||
GSimpleAction *reset_action;
|
||||
gboolean has_colors;
|
||||
char *palette;
|
||||
GtkCheckButton *default_check;
|
||||
};
|
||||
|
||||
struct _FontColorsClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (FontColors, font_colors, GTK_TYPE_WIDGET);
|
||||
|
||||
static Pango2Font *
|
||||
get_font (FontColors *self)
|
||||
{
|
||||
Pango2Context *context;
|
||||
|
||||
context = gtk_widget_get_pango_context (GTK_WIDGET (self));
|
||||
return pango2_context_load_font (context, self->font_desc);
|
||||
}
|
||||
|
||||
static void
|
||||
palette_changed (GtkCheckButton *button,
|
||||
FontColors *self)
|
||||
{
|
||||
g_free (self->palette);
|
||||
self->palette = g_strdup ((const char *) g_object_get_data (G_OBJECT (button), "palette"));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PALETTE]);
|
||||
}
|
||||
|
||||
static void
|
||||
update_colors (FontColors *self)
|
||||
{
|
||||
Pango2Font *font;
|
||||
hb_font_t *hb_font;
|
||||
hb_face_t *hb_face;
|
||||
GtkWidget *child;
|
||||
GtkWidget *check;
|
||||
unsigned int n_colors;
|
||||
hb_color_t *colors;
|
||||
GtkWidget *box;
|
||||
|
||||
g_object_ref (self->label);
|
||||
|
||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (self->grid))))
|
||||
gtk_grid_remove (self->grid, child);
|
||||
|
||||
gtk_grid_attach (self->grid, GTK_WIDGET (self->label), 0, -4, 2, 1);
|
||||
g_object_unref (self->label);
|
||||
|
||||
self->default_check = NULL;
|
||||
|
||||
font = get_font (self);
|
||||
hb_font = pango2_font_get_hb_font (font);
|
||||
hb_face = hb_font_get_face (hb_font);
|
||||
|
||||
self->has_colors = hb_ot_color_has_palettes (hb_face);
|
||||
gtk_widget_set_visible (GTK_WIDGET (self), self->has_colors);
|
||||
if (!self->has_colors)
|
||||
{
|
||||
g_simple_action_set_enabled (self->reset_action, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
|
||||
gtk_grid_attach (self->grid, box, 0, -3, 2, 1);
|
||||
|
||||
check = gtk_check_button_new_with_label ("Default");
|
||||
g_object_set_data (G_OBJECT (check), "palette", (gpointer)"default");
|
||||
if (g_strcmp0 ("default", self->palette) == 0)
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (check), TRUE);
|
||||
g_signal_connect (check, "toggled", G_CALLBACK (palette_changed), self);
|
||||
gtk_box_append (GTK_BOX (box), check);
|
||||
self->default_check = GTK_CHECK_BUTTON (check);
|
||||
|
||||
check = gtk_check_button_new_with_label ("Light");
|
||||
g_object_set_data (G_OBJECT (check), "palette", (gpointer)"light");
|
||||
if (g_strcmp0 ("light", self->palette) == 0)
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (check), TRUE);
|
||||
g_signal_connect (check, "toggled", G_CALLBACK (palette_changed), self);
|
||||
gtk_check_button_set_group (GTK_CHECK_BUTTON (check), self->default_check);
|
||||
gtk_box_append (GTK_BOX (box), check);
|
||||
|
||||
check = gtk_check_button_new_with_label ("Dark");
|
||||
g_object_set_data (G_OBJECT (check), "palette", (gpointer)"dark");
|
||||
if (g_strcmp0 ("dark", self->palette) == 0)
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (check), TRUE);
|
||||
g_signal_connect (check, "toggled", G_CALLBACK (palette_changed), self);
|
||||
gtk_check_button_set_group (GTK_CHECK_BUTTON (check), self->default_check);
|
||||
gtk_box_append (GTK_BOX (box), check);
|
||||
|
||||
for (int i = 0; i < hb_ot_color_palette_get_count (hb_face); i++)
|
||||
{
|
||||
char *id = g_strdup_printf ("palette%d", i);
|
||||
char *label = g_strdup_printf ("Palette %d", i);
|
||||
GtkWidget *palette;
|
||||
|
||||
check = gtk_check_button_new_with_label (label);
|
||||
g_object_set_data_full (G_OBJECT (check), "palette", id, g_free);
|
||||
if (g_strcmp0 (id, self->palette) == 0)
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (check), TRUE);
|
||||
g_signal_connect (check, "toggled", G_CALLBACK (palette_changed), self);
|
||||
gtk_check_button_set_group (GTK_CHECK_BUTTON (check), self->default_check);
|
||||
gtk_grid_attach (self->grid, check, 0, i, 1, 1);
|
||||
|
||||
n_colors = hb_ot_color_palette_get_colors (hb_face, i, 0, NULL, NULL);
|
||||
colors = g_new (hb_color_t, n_colors);
|
||||
n_colors = hb_ot_color_palette_get_colors (hb_face, i, 0, &n_colors, colors);
|
||||
|
||||
palette = gtk_grid_new ();
|
||||
gtk_widget_set_valign (palette, GTK_ALIGN_CENTER);
|
||||
gtk_grid_attach (self->grid, palette, 1, i, 1, 1);
|
||||
|
||||
/* HACK - defeat first-child/last-child theming */
|
||||
gtk_grid_attach (GTK_GRID (palette), gtk_picture_new (), -1, 0, 1, 1);
|
||||
|
||||
for (int k = 0; k < n_colors; k++)
|
||||
{
|
||||
GtkWidget *swatch;
|
||||
swatch = g_object_new (g_type_from_name ("GtkColorSwatch"),
|
||||
"rgba", &(GdkRGBA){ hb_color_get_red (colors[k])/255.,
|
||||
hb_color_get_green (colors[k])/255.,
|
||||
hb_color_get_blue (colors[k])/255.,
|
||||
hb_color_get_alpha (colors[k])/255.},
|
||||
"selectable", FALSE,
|
||||
"has-menu", FALSE,
|
||||
"can-drag", FALSE,
|
||||
"width-request", 16,
|
||||
"height-request", 16,
|
||||
NULL);
|
||||
gtk_grid_attach (GTK_GRID (palette), swatch, k % 6, k / 6, 1, 1);
|
||||
}
|
||||
|
||||
/* HACK - defeat first-child/last-child theming */
|
||||
gtk_grid_attach (GTK_GRID (palette), gtk_picture_new (), 6, 0, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
reset (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
FontColors *self)
|
||||
{
|
||||
g_free (self->palette);
|
||||
self->palette = g_strdup (PANGO2_COLOR_PALETTE_DEFAULT);
|
||||
if (self->has_colors)
|
||||
gtk_check_button_set_active (self->default_check, TRUE);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PALETTE]);
|
||||
g_simple_action_set_enabled (self->reset_action, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
font_colors_init (FontColors *self)
|
||||
{
|
||||
self->palette = g_strdup (PANGO2_COLOR_PALETTE_DEFAULT);
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
self->reset_action = g_simple_action_new ("reset", NULL);
|
||||
g_simple_action_set_enabled (self->reset_action, FALSE);
|
||||
g_signal_connect (self->reset_action, "activate", G_CALLBACK (reset), self);
|
||||
}
|
||||
|
||||
static void
|
||||
font_colors_dispose (GObject *object)
|
||||
{
|
||||
gtk_widget_clear_template (GTK_WIDGET (object), FONT_COLORS_TYPE);
|
||||
|
||||
G_OBJECT_CLASS (font_colors_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
font_colors_finalize (GObject *object)
|
||||
{
|
||||
FontColors *self = FONT_COLORS (object);
|
||||
|
||||
g_clear_pointer (&self->font_desc, pango2_font_description_free);
|
||||
g_free (self->palette);
|
||||
|
||||
G_OBJECT_CLASS (font_colors_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
font_colors_set_property (GObject *object,
|
||||
unsigned int prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
FontColors *self = FONT_COLORS (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FONT_DESC:
|
||||
pango2_font_description_free (self->font_desc);
|
||||
self->font_desc = pango2_font_description_copy (g_value_get_boxed (value));
|
||||
update_colors (self);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
font_colors_get_property (GObject *object,
|
||||
unsigned int prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
FontColors *self = FONT_COLORS (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PALETTE:
|
||||
g_value_set_string (value, self->palette);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
font_colors_class_init (FontColorsClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->dispose = font_colors_dispose;
|
||||
object_class->finalize = font_colors_finalize;
|
||||
object_class->get_property = font_colors_get_property;
|
||||
object_class->set_property = font_colors_set_property;
|
||||
|
||||
properties[PROP_FONT_DESC] =
|
||||
g_param_spec_boxed ("font-desc", "", "",
|
||||
PANGO2_TYPE_FONT_DESCRIPTION,
|
||||
G_PARAM_WRITABLE);
|
||||
|
||||
properties[PROP_PALETTE] =
|
||||
g_param_spec_string ("palette", "", "",
|
||||
PANGO2_COLOR_PALETTE_DEFAULT,
|
||||
G_PARAM_READABLE);
|
||||
|
||||
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/fontexplorer/fontcolors.ui");
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontColors, grid);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontColors, label);
|
||||
|
||||
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "fontcolors");
|
||||
}
|
||||
|
||||
FontColors *
|
||||
font_colors_new (void)
|
||||
{
|
||||
return g_object_new (FONT_COLORS_TYPE, NULL);
|
||||
}
|
||||
|
||||
GAction *
|
||||
font_colors_get_reset_action (FontColors *self)
|
||||
{
|
||||
return G_ACTION (self->reset_action);
|
||||
}
|
||||
16
demos/font-explorer/fontcolors.h
Normal file
16
demos/font-explorer/fontcolors.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define FONT_COLORS_TYPE (font_colors_get_type ())
|
||||
#define FONT_COLORS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_COLORS_TYPE, FontColors))
|
||||
|
||||
|
||||
typedef struct _FontColors FontColors;
|
||||
typedef struct _FontColorsClass FontColorsClass;
|
||||
|
||||
|
||||
GType font_colors_get_type (void);
|
||||
FontColors * font_colors_new (void);
|
||||
GAction * font_colors_get_reset_action (FontColors *self);
|
||||
25
demos/font-explorer/fontcolors.ui
Normal file
25
demos/font-explorer/fontcolors.ui
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="FontColors" parent="GtkWidget">
|
||||
<property name="layout-manager"><object class="GtkBinLayout"/></property>
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid">
|
||||
<child>
|
||||
<object class="GtkLabel" id="label">
|
||||
<property name="label" translatable="yes">Colors</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="heading"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="row">-2</property>
|
||||
<property name="column">0</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
271
demos/font-explorer/fontcontrols.c
Normal file
271
demos/font-explorer/fontcontrols.c
Normal file
@@ -0,0 +1,271 @@
|
||||
#include "fontcontrols.h"
|
||||
#include "rangeedit.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <hb-ot.h>
|
||||
|
||||
enum {
|
||||
PROP_SIZE = 1,
|
||||
PROP_LETTERSPACING,
|
||||
PROP_LINE_HEIGHT,
|
||||
PROP_FOREGROUND,
|
||||
PROP_BACKGROUND,
|
||||
PROP_DISABLE_SIZE,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
struct _FontControls
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
GtkAdjustment *size_adjustment;
|
||||
GtkAdjustment *letterspacing_adjustment;
|
||||
GtkAdjustment *line_height_adjustment;
|
||||
GtkColorButton *foreground;
|
||||
GtkColorButton *background;
|
||||
|
||||
GSimpleAction *reset_action;
|
||||
gboolean disable_size;
|
||||
};
|
||||
|
||||
struct _FontControlsClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FontControls, font_controls, GTK_TYPE_WIDGET);
|
||||
|
||||
static void
|
||||
size_changed (GtkAdjustment *adjustment,
|
||||
FontControls *self)
|
||||
{
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SIZE]);
|
||||
g_simple_action_set_enabled (self->reset_action, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
letterspacing_changed (GtkAdjustment *adjustment,
|
||||
FontControls *self)
|
||||
{
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_LETTERSPACING]);
|
||||
g_simple_action_set_enabled (self->reset_action, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
line_height_changed (GtkAdjustment *adjustment,
|
||||
FontControls *self)
|
||||
{
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_LINE_HEIGHT]);
|
||||
g_simple_action_set_enabled (self->reset_action, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
color_set (GtkColorButton *button,
|
||||
GParamSpec *pspec,
|
||||
FontControls *self)
|
||||
{
|
||||
if (button == self->foreground)
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FOREGROUND]);
|
||||
else
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_BACKGROUND]);
|
||||
g_simple_action_set_enabled (self->reset_action, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
swap_colors (GtkButton *button,
|
||||
FontControls *self)
|
||||
{
|
||||
GdkRGBA fg;
|
||||
GdkRGBA bg;
|
||||
|
||||
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (self->foreground), &fg);
|
||||
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (self->background), &bg);
|
||||
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (self->foreground), &bg);
|
||||
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (self->background), &fg);
|
||||
}
|
||||
|
||||
static void
|
||||
reset (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
FontControls *self)
|
||||
{
|
||||
gtk_adjustment_set_value (self->size_adjustment, 12.);
|
||||
gtk_adjustment_set_value (self->letterspacing_adjustment, 0.);
|
||||
gtk_adjustment_set_value (self->line_height_adjustment, 1.);
|
||||
|
||||
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (self->foreground), &(GdkRGBA){0., 0., 0., 1.0 });
|
||||
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (self->background), &(GdkRGBA){1., 1., 1., 1.0 });
|
||||
|
||||
g_simple_action_set_enabled (self->reset_action, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
font_controls_init (FontControls *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
self->reset_action = g_simple_action_new ("reset", NULL);
|
||||
g_simple_action_set_enabled (self->reset_action, FALSE);
|
||||
g_signal_connect (self->reset_action, "activate", G_CALLBACK (reset), self);
|
||||
}
|
||||
|
||||
static void
|
||||
font_controls_dispose (GObject *object)
|
||||
{
|
||||
gtk_widget_clear_template (GTK_WIDGET (object), FONT_CONTROLS_TYPE);
|
||||
|
||||
G_OBJECT_CLASS (font_controls_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
font_controls_finalize (GObject *object)
|
||||
{
|
||||
//FontControls *self = FONT_CONTROLS (object);
|
||||
|
||||
G_OBJECT_CLASS (font_controls_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
font_controls_set_property (GObject *object,
|
||||
unsigned int prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
FontControls *self = FONT_CONTROLS (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SIZE:
|
||||
gtk_adjustment_set_value (self->size_adjustment, g_value_get_float (value));
|
||||
break;
|
||||
|
||||
case PROP_DISABLE_SIZE:
|
||||
self->disable_size = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
font_controls_get_property (GObject *object,
|
||||
unsigned int prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
FontControls *self = FONT_CONTROLS (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SIZE:
|
||||
g_value_set_float (value, gtk_adjustment_get_value (self->size_adjustment));
|
||||
break;
|
||||
|
||||
case PROP_LETTERSPACING:
|
||||
g_value_set_int (value, (int) gtk_adjustment_get_value (self->letterspacing_adjustment));
|
||||
break;
|
||||
|
||||
case PROP_LINE_HEIGHT:
|
||||
g_value_set_float (value, gtk_adjustment_get_value (self->line_height_adjustment));
|
||||
break;
|
||||
|
||||
case PROP_FOREGROUND:
|
||||
{
|
||||
GdkRGBA rgba;
|
||||
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (self->foreground), &rgba);
|
||||
g_value_set_boxed (value, &rgba);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_BACKGROUND:
|
||||
{
|
||||
GdkRGBA rgba;
|
||||
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (self->background), &rgba);
|
||||
g_value_set_boxed (value, &rgba);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_DISABLE_SIZE:
|
||||
g_value_set_boolean (value, self->disable_size);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
font_controls_class_init (FontControlsClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
g_type_ensure (RANGE_EDIT_TYPE);
|
||||
|
||||
object_class->dispose = font_controls_dispose;
|
||||
object_class->finalize = font_controls_finalize;
|
||||
object_class->get_property = font_controls_get_property;
|
||||
object_class->set_property = font_controls_set_property;
|
||||
|
||||
properties[PROP_SIZE] =
|
||||
g_param_spec_float ("size", "", "",
|
||||
0., 100., 12.,
|
||||
G_PARAM_READABLE);
|
||||
|
||||
properties[PROP_LETTERSPACING] =
|
||||
g_param_spec_int ("letterspacing", "", "",
|
||||
-G_MAXINT, G_MAXINT, 0,
|
||||
G_PARAM_READABLE);
|
||||
|
||||
properties[PROP_LINE_HEIGHT] =
|
||||
g_param_spec_float ("line-height", "", "",
|
||||
0., 100., 1.,
|
||||
G_PARAM_READABLE);
|
||||
|
||||
properties[PROP_FOREGROUND] =
|
||||
g_param_spec_boxed ("foreground", "", "",
|
||||
GDK_TYPE_RGBA,
|
||||
G_PARAM_READABLE);
|
||||
|
||||
properties[PROP_BACKGROUND] =
|
||||
g_param_spec_boxed ("background", "", "",
|
||||
GDK_TYPE_RGBA,
|
||||
G_PARAM_READABLE);
|
||||
|
||||
properties[PROP_DISABLE_SIZE] =
|
||||
g_param_spec_boolean ("disable-size", "", "",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/fontexplorer/fontcontrols.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontControls, size_adjustment);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontControls, letterspacing_adjustment);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontControls, line_height_adjustment);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontControls, foreground);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontControls, background);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), size_changed);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), letterspacing_changed);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), line_height_changed);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), color_set);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), swap_colors);
|
||||
|
||||
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "fontcontrols");
|
||||
}
|
||||
|
||||
FontControls *
|
||||
font_controls_new (void)
|
||||
{
|
||||
return g_object_new (FONT_CONTROLS_TYPE, NULL);
|
||||
}
|
||||
|
||||
GAction *
|
||||
font_controls_get_reset_action (FontControls *self)
|
||||
{
|
||||
return G_ACTION (self->reset_action);
|
||||
}
|
||||
16
demos/font-explorer/fontcontrols.h
Normal file
16
demos/font-explorer/fontcontrols.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define FONT_CONTROLS_TYPE (font_controls_get_type ())
|
||||
#define FONT_CONTROLS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_CONTROLS_TYPE, FontControls))
|
||||
|
||||
|
||||
typedef struct _FontControls FontControls;
|
||||
typedef struct _FontControlsClass FontControlsClass;
|
||||
|
||||
|
||||
GType font_controls_get_type (void);
|
||||
FontControls * font_controls_new (void);
|
||||
GAction * font_controls_get_reset_action (FontControls *self);
|
||||
175
demos/font-explorer/fontcontrols.ui
Normal file
175
demos/font-explorer/fontcontrols.ui
Normal file
@@ -0,0 +1,175 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="FontControls" parent="GtkWidget">
|
||||
<property name="layout-manager"><object class="GtkGridLayout"/></property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="sensitive" bind-source="FontControls" bind-property="disable-size" bind-flags="invert-boolean"/>
|
||||
<property name="label">Size</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="valign">baseline</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="RangeEdit">
|
||||
<property name="sensitive" bind-source="FontControls" bind-property="disable-size" bind-flags="invert-boolean"/>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="width-request">160</property>
|
||||
<property name="valign">baseline</property>
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment" id="size_adjustment">
|
||||
<property name="lower">7</property>
|
||||
<property name="upper">100</property>
|
||||
<property name="value">14</property>
|
||||
<property name="step_increment">0.5</property>
|
||||
<property name="page_increment">10</property>
|
||||
<signal name="value-changed" handler="size_changed"/>
|
||||
</object>
|
||||
</property>
|
||||
<property name="default-value">12</property>
|
||||
<property name="n-chars">5</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">0</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Letterspacing</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="valign">baseline</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="RangeEdit">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="width-request">160</property>
|
||||
<property name="valign">baseline</property>
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment" id="letterspacing_adjustment">
|
||||
<property name="lower">-1024</property>
|
||||
<property name="upper">8192</property>
|
||||
<property name="value">0</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">512</property>
|
||||
<signal name="value-changed" handler="letterspacing_changed"/>
|
||||
</object>
|
||||
</property>
|
||||
<property name="default-value">0</property>
|
||||
<property name="n-chars">5</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">1</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Line Height</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="valign">baseline</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="RangeEdit">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="width-request">160</property>
|
||||
<property name="valign">baseline</property>
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment" id="line_height_adjustment">
|
||||
<property name="lower">0.75</property>
|
||||
<property name="upper">2.5</property>
|
||||
<property name="value">1.0</property>
|
||||
<property name="step_increment">0.1</property>
|
||||
<property name="page_increment">1</property>
|
||||
<signal name="value-changed" handler="line_height_changed"/>
|
||||
</object>
|
||||
</property>
|
||||
<property name="default-value">1</property>
|
||||
<property name="n-chars">5</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">2</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Foreground</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="valign">baseline</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColorButton" id="foreground">
|
||||
<property name="rgba">black</property>
|
||||
<signal name="notify::rgba" handler="color_set"/>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Background</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="valign">baseline</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">4</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColorButton" id="background">
|
||||
<property name="rgba">white</property>
|
||||
<signal name="notify::rgba" handler="color_set"/>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">4</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">object-flip-vertical-symbolic</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<style>
|
||||
<class name="circular"/>
|
||||
</style>
|
||||
<signal name="clicked" handler="swap_colors"/>
|
||||
<layout>
|
||||
<property name="column">2</property>
|
||||
<property name="row">3</property>
|
||||
<property name="row-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
20
demos/font-explorer/fontexplorer.css
Normal file
20
demos/font-explorer/fontexplorer.css
Normal file
@@ -0,0 +1,20 @@
|
||||
box.sidebar {
|
||||
padding: 20px;
|
||||
border-spacing: 20px;
|
||||
}
|
||||
fontcontrols {
|
||||
border-spacing: 10px;
|
||||
}
|
||||
fontvariations > grid {
|
||||
border-spacing: 10px;
|
||||
}
|
||||
fontcolors > grid {
|
||||
border-spacing: 10px;
|
||||
}
|
||||
samplechooser {
|
||||
border-spacing: 10px;
|
||||
}
|
||||
fontview {
|
||||
padding: 10px;
|
||||
border-spacing: 10px;
|
||||
}
|
||||
14
demos/font-explorer/fontexplorer.gresource.xml
Normal file
14
demos/font-explorer/fontexplorer.gresource.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/org/gtk/fontexplorer">
|
||||
<file preprocess="xml-stripblanks">fontexplorerwin.ui</file>
|
||||
<file preprocess="xml-stripblanks">fontview.ui</file>
|
||||
<file preprocess="xml-stripblanks">fontcontrols.ui</file>
|
||||
<file preprocess="xml-stripblanks">samplechooser.ui</file>
|
||||
<file preprocess="xml-stripblanks">fontcolors.ui</file>
|
||||
<file preprocess="xml-stripblanks">fontfeatures.ui</file>
|
||||
<file preprocess="xml-stripblanks">fontvariations.ui</file>
|
||||
<file preprocess="xml-stripblanks">rangeedit.ui</file>
|
||||
<file>fontexplorer.css</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
165
demos/font-explorer/fontexplorerapp.c
Normal file
165
demos/font-explorer/fontexplorerapp.c
Normal file
@@ -0,0 +1,165 @@
|
||||
#include "config.h"
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "fontexplorerapp.h"
|
||||
#include "fontexplorerwin.h"
|
||||
|
||||
#include "demo_conf.h"
|
||||
|
||||
struct _FontExplorerApp
|
||||
{
|
||||
GtkApplication parent;
|
||||
};
|
||||
|
||||
struct _FontExplorerAppClass
|
||||
{
|
||||
GtkApplicationClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FontExplorerApp, font_explorer_app, GTK_TYPE_APPLICATION);
|
||||
|
||||
static void
|
||||
font_explorer_app_init (FontExplorerApp *app)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
quit_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer app)
|
||||
{
|
||||
g_application_quit (G_APPLICATION (app));
|
||||
}
|
||||
|
||||
static void
|
||||
inspector_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer app)
|
||||
{
|
||||
gtk_window_set_interactive_debugging (TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
about_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkApplication *app = user_data;
|
||||
const char *authors[] = {
|
||||
"The GTK Team",
|
||||
NULL
|
||||
};
|
||||
char *icon_theme;
|
||||
char *version;
|
||||
GString *s;
|
||||
char *os_name;
|
||||
char *os_version;
|
||||
|
||||
g_object_get (gtk_settings_get_default (),
|
||||
"gtk-icon-theme-name", &icon_theme,
|
||||
NULL);
|
||||
|
||||
s = g_string_new ("");
|
||||
|
||||
os_name = g_get_os_info (G_OS_INFO_KEY_NAME);
|
||||
os_version = g_get_os_info (G_OS_INFO_KEY_VERSION_ID);
|
||||
if (os_name && os_version)
|
||||
g_string_append_printf (s, "OS\t%s %s\n\n", os_name, os_version);
|
||||
g_string_append (s, "System libraries\n");
|
||||
g_string_append_printf (s, "\tGLib\t%d.%d.%d\n",
|
||||
glib_major_version,
|
||||
glib_minor_version,
|
||||
glib_micro_version);
|
||||
g_string_append_printf (s, "\tPango2\t%s\n",
|
||||
pango2_version_string ());
|
||||
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
g_string_append_printf (s, "\nIcon theme\n\t%s", icon_theme);
|
||||
version = g_strdup_printf ("%s%s%s\nRunning against GTK %d.%d.%d",
|
||||
PACKAGE_VERSION,
|
||||
g_strcmp0 (PROFILE, "devel") == 0 ? "-" : "",
|
||||
g_strcmp0 (PROFILE, "devel") == 0 ? VCS_TAG : "",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
|
||||
gtk_show_about_dialog (GTK_WINDOW (gtk_application_get_active_window (app)),
|
||||
"program-name", g_strcmp0 (PROFILE, "devel") == 0
|
||||
? "GTK Font Explorer (Development)"
|
||||
: "GTK Font Explorer",
|
||||
"version", version,
|
||||
"copyright", "© 1997—2021 The GTK Team",
|
||||
"license-type", GTK_LICENSE_LGPL_2_1,
|
||||
"website", "http://www.gtk.org",
|
||||
"comments", "Program to explore font features",
|
||||
"authors", authors,
|
||||
"logo-icon-name", "org.gtk.FontExplorer",
|
||||
"title", "About GTK Font Explorer",
|
||||
"system-information", s->str,
|
||||
NULL);
|
||||
|
||||
g_string_free (s, TRUE);
|
||||
g_free (version);
|
||||
g_free (icon_theme);
|
||||
g_free (os_name);
|
||||
g_free (os_version);
|
||||
}
|
||||
|
||||
static GActionEntry app_entries[] =
|
||||
{
|
||||
{ "quit", quit_activated, NULL, NULL, NULL },
|
||||
{ "inspector", inspector_activated, NULL, NULL, NULL },
|
||||
{ "about", about_activated, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
font_explorer_app_startup (GApplication *app)
|
||||
{
|
||||
const char *quit_accels[2] = { "<Ctrl>Q", NULL };
|
||||
GtkCssProvider *provider;
|
||||
|
||||
G_APPLICATION_CLASS (font_explorer_app_parent_class)->startup (app);
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (app),
|
||||
app_entries, G_N_ELEMENTS (app_entries),
|
||||
app);
|
||||
gtk_application_set_accels_for_action (GTK_APPLICATION (app),
|
||||
"app.quit",
|
||||
quit_accels);
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (provider, "/org/gtk/fontexplorer/fontexplorer.css");
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
}
|
||||
|
||||
static void
|
||||
font_explorer_app_activate (GApplication *app)
|
||||
{
|
||||
FontExplorerWindow *win;
|
||||
|
||||
win = font_explorer_window_new (FONT_EXPLORER_APP (app));
|
||||
|
||||
if (g_strcmp0 (PROFILE, "devel") == 0)
|
||||
gtk_widget_add_css_class (GTK_WIDGET (win), "devel");
|
||||
|
||||
gtk_window_present (GTK_WINDOW (win));
|
||||
}
|
||||
|
||||
static void
|
||||
font_explorer_app_class_init (FontExplorerAppClass *class)
|
||||
{
|
||||
G_APPLICATION_CLASS (class)->startup = font_explorer_app_startup;
|
||||
G_APPLICATION_CLASS (class)->activate = font_explorer_app_activate;
|
||||
}
|
||||
|
||||
FontExplorerApp *
|
||||
font_explorer_app_new (void)
|
||||
{
|
||||
return g_object_new (FONT_EXPLORER_APP_TYPE,
|
||||
"application-id", "org.gtk.FontExplorer",
|
||||
NULL);
|
||||
}
|
||||
15
demos/font-explorer/fontexplorerapp.h
Normal file
15
demos/font-explorer/fontexplorerapp.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define FONT_EXPLORER_APP_TYPE (font_explorer_app_get_type ())
|
||||
#define FONT_EXPLORER_APP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_EXPLORER_APP_TYPE, FontExplorerApp))
|
||||
|
||||
|
||||
typedef struct _FontExplorerApp FontExplorerApp;
|
||||
typedef struct _FontExplorerAppClass FontExplorerAppClass;
|
||||
|
||||
|
||||
GType font_explorer_app_get_type (void);
|
||||
FontExplorerApp * font_explorer_app_new (void);
|
||||
131
demos/font-explorer/fontexplorerwin.c
Normal file
131
demos/font-explorer/fontexplorerwin.c
Normal file
@@ -0,0 +1,131 @@
|
||||
#include "fontexplorerapp.h"
|
||||
#include "fontexplorerwin.h"
|
||||
#include "fontview.h"
|
||||
#include "fontcontrols.h"
|
||||
#include "samplechooser.h"
|
||||
#include "fontcolors.h"
|
||||
#include "fontfeatures.h"
|
||||
#include "fontvariations.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
struct _FontExplorerWindow
|
||||
{
|
||||
GtkApplicationWindow parent;
|
||||
|
||||
GtkFontButton *fontbutton;
|
||||
FontControls *controls;
|
||||
FontFeatures *features;
|
||||
FontVariations *variations;
|
||||
FontColors *colors;
|
||||
FontView *view;
|
||||
};
|
||||
|
||||
struct _FontExplorerWindowClass
|
||||
{
|
||||
GtkApplicationWindowClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FontExplorerWindow, font_explorer_window, GTK_TYPE_APPLICATION_WINDOW);
|
||||
|
||||
static void
|
||||
reset (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
FontExplorerWindow *win)
|
||||
{
|
||||
g_action_activate (font_controls_get_reset_action (win->controls), NULL);
|
||||
g_action_activate (font_features_get_reset_action (win->features), NULL);
|
||||
g_action_activate (font_variations_get_reset_action (win->variations), NULL);
|
||||
g_action_activate (font_colors_get_reset_action (win->colors), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
update_reset (GSimpleAction *action,
|
||||
GParamSpec *pspec,
|
||||
FontExplorerWindow *win)
|
||||
{
|
||||
gboolean enabled;
|
||||
GAction *reset_action;
|
||||
|
||||
enabled = g_action_get_enabled (font_controls_get_reset_action (win->controls)) ||
|
||||
g_action_get_enabled (font_features_get_reset_action (win->features)) ||
|
||||
g_action_get_enabled (font_variations_get_reset_action (win->variations)) ||
|
||||
g_action_get_enabled (font_colors_get_reset_action (win->colors));
|
||||
|
||||
reset_action = g_action_map_lookup_action (G_ACTION_MAP (win), "reset");
|
||||
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (reset_action), enabled);
|
||||
}
|
||||
|
||||
static void
|
||||
font_explorer_window_init (FontExplorerWindow *win)
|
||||
{
|
||||
GSimpleAction *reset_action;
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (win));
|
||||
|
||||
reset_action = g_simple_action_new ("reset", NULL);
|
||||
g_signal_connect (reset_action, "activate", G_CALLBACK (reset), win);
|
||||
g_signal_connect (font_controls_get_reset_action (win->controls),
|
||||
"notify::enabled", G_CALLBACK (update_reset), win);
|
||||
g_signal_connect (font_variations_get_reset_action (win->variations),
|
||||
"notify::enabled", G_CALLBACK (update_reset), win);
|
||||
g_signal_connect (font_colors_get_reset_action (win->colors),
|
||||
"notify::enabled", G_CALLBACK (update_reset), win);
|
||||
g_signal_connect (font_features_get_reset_action (win->features),
|
||||
"notify::enabled", G_CALLBACK (update_reset), win);
|
||||
|
||||
g_action_map_add_action (G_ACTION_MAP (win), G_ACTION (reset_action));
|
||||
update_reset (NULL, NULL, win);
|
||||
}
|
||||
|
||||
static void
|
||||
font_explorer_window_dispose (GObject *object)
|
||||
{
|
||||
gtk_widget_clear_template (GTK_WIDGET (object), FONT_EXPLORER_WINDOW_TYPE);
|
||||
|
||||
G_OBJECT_CLASS (font_explorer_window_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
font_explorer_window_finalize (GObject *object)
|
||||
{
|
||||
// FontExplorerWindow *win = FONT_EXPLORER_WINDOW (object);
|
||||
|
||||
G_OBJECT_CLASS (font_explorer_window_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
font_explorer_window_class_init (FontExplorerWindowClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
g_type_ensure (FONT_VIEW_TYPE);
|
||||
g_type_ensure (FONT_CONTROLS_TYPE);
|
||||
g_type_ensure (SAMPLE_CHOOSER_TYPE);
|
||||
g_type_ensure (FONT_VARIATIONS_TYPE);
|
||||
g_type_ensure (FONT_COLORS_TYPE);
|
||||
g_type_ensure (FONT_FEATURES_TYPE);
|
||||
|
||||
object_class->dispose = font_explorer_window_dispose;
|
||||
object_class->finalize = font_explorer_window_finalize;
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/fontexplorer/fontexplorerwin.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, fontbutton);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, controls);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, variations);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, colors);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, features);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, view);
|
||||
|
||||
}
|
||||
|
||||
FontExplorerWindow *
|
||||
font_explorer_window_new (FontExplorerApp *app)
|
||||
{
|
||||
return g_object_new (FONT_EXPLORER_WINDOW_TYPE, "application", app, NULL);
|
||||
}
|
||||
16
demos/font-explorer/fontexplorerwin.h
Normal file
16
demos/font-explorer/fontexplorerwin.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "fontexplorerapp.h"
|
||||
|
||||
|
||||
#define FONT_EXPLORER_WINDOW_TYPE (font_explorer_window_get_type ())
|
||||
#define FONT_EXPLORER_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_EXPLORER_WINDOW_TYPE, FontExplorerWindow))
|
||||
|
||||
|
||||
typedef struct _FontExplorerWindow FontExplorerWindow;
|
||||
typedef struct _FontExplorerWindowClass FontExplorerWindowClass;
|
||||
|
||||
|
||||
GType font_explorer_window_get_type (void);
|
||||
FontExplorerWindow * font_explorer_window_new (FontExplorerApp *app);
|
||||
100
demos/font-explorer/fontexplorerwin.ui
Normal file
100
demos/font-explorer/fontexplorerwin.ui
Normal file
@@ -0,0 +1,100 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<menu id="gear_menu">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Inspector</attribute>
|
||||
<attribute name="action">app.inspector</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_About GTK Font Explorer</attribute>
|
||||
<attribute name="action">app.about</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
<template class="FontExplorerWindow" parent="GtkApplicationWindow">
|
||||
<property name="title" translatable="yes">Font Explorer</property>
|
||||
<property name="default-width">1024</property>
|
||||
<property name="default-height">768</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<child>
|
||||
<object class="GtkButton" id="reset">
|
||||
<property name="receives-default">1</property>
|
||||
<property name="tooltip-text">Reset</property>
|
||||
<property name="icon-name">view-refresh-symbolic</property>
|
||||
<property name="action-name">win.reset</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkMenuButton" id="gear_menu_button">
|
||||
<property name="focus-on-click">0</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="menu-model">gear_menu</property>
|
||||
<property name="icon-name">open-menu-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<style>
|
||||
<class name="sidebar"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkFontButton" id="fontbutton">
|
||||
<property name="level">family|style</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="FontControls" id="controls">
|
||||
<property name="disable-size" bind-source="view" bind-property="ignore-size" bind-flags="sync-create"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="SampleChooser" id="samplechooser"/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="FontVariations" id="variations">
|
||||
<property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="FontFeatures" id="features">
|
||||
<property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
|
||||
<property name="language" bind-source="fontbutton" bind-flags="sync-create"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="FontColors" id="colors">
|
||||
<property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="FontView" id="view">
|
||||
<property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
|
||||
<property name="size" bind-source="controls" bind-flags="sync-create"/>
|
||||
<property name="letterspacing" bind-source="controls" bind-flags="sync-create"/>
|
||||
<property name="line-height" bind-source="controls" bind-flags="sync-create"/>
|
||||
<property name="foreground" bind-source="controls" bind-flags="sync-create"/>
|
||||
<property name="background" bind-source="controls" bind-flags="sync-create"/>
|
||||
<property name="sample-text" bind-source="samplechooser" bind-flags="sync-create"/>
|
||||
<property name="features" bind-source="features" bind-flags="sync-create"/>
|
||||
<property name="variations" bind-source="variations" bind-flags="sync-create"/>
|
||||
<property name="palette" bind-source="colors" bind-flags="sync-create"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
727
demos/font-explorer/fontfeatures.c
Normal file
727
demos/font-explorer/fontfeatures.c
Normal file
@@ -0,0 +1,727 @@
|
||||
#include "fontfeatures.h"
|
||||
#include <gtk/gtk.h>
|
||||
#include <hb-ot.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "open-type-layout.h"
|
||||
#include "language-names.h"
|
||||
|
||||
|
||||
enum {
|
||||
PROP_FONT_DESC = 1,
|
||||
PROP_LANGUAGE,
|
||||
PROP_FEATURES,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
typedef struct {
|
||||
unsigned int tag;
|
||||
const char *name;
|
||||
GtkWidget *feat;
|
||||
} FeatureItem;
|
||||
|
||||
struct _FontFeatures
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
GtkGrid *label;
|
||||
GtkGrid *grid;
|
||||
Pango2FontDescription *font_desc;
|
||||
GSimpleAction *reset_action;
|
||||
Pango2Language *lang;
|
||||
GList *feature_items;
|
||||
};
|
||||
|
||||
struct _FontFeaturesClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FontFeatures, font_features, GTK_TYPE_WIDGET);
|
||||
|
||||
static Pango2Font *
|
||||
get_font (FontFeatures *self)
|
||||
{
|
||||
Pango2Context *context;
|
||||
|
||||
context = gtk_widget_get_pango_context (GTK_WIDGET (self));
|
||||
return pango2_context_load_font (context, self->font_desc);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_ssNN (const char *buf)
|
||||
{
|
||||
return g_str_has_prefix (buf, "ss") && g_ascii_isdigit (buf[2]) && g_ascii_isdigit (buf[3]);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_cvNN (const char *buf)
|
||||
{
|
||||
return g_str_has_prefix (buf, "cv") && g_ascii_isdigit (buf[2]) && g_ascii_isdigit (buf[3]);
|
||||
}
|
||||
|
||||
static char *
|
||||
get_feature_display_name (unsigned int tag)
|
||||
{
|
||||
int i;
|
||||
static char buf[5] = { 0, };
|
||||
|
||||
if (tag == HB_TAG ('x', 'x', 'x', 'x'))
|
||||
return g_strdup (_("Default"));
|
||||
|
||||
hb_tag_to_string (tag, buf);
|
||||
if (is_ssNN (buf))
|
||||
{
|
||||
int num = (buf[2] - '0') * 10 + (buf[3] - '0');
|
||||
return g_strdup_printf (g_dpgettext2 (NULL, "OpenType layout", "Stylistic Set %d"), num);
|
||||
}
|
||||
else if (is_cvNN (buf))
|
||||
{
|
||||
int num = (buf[2] - '0') * 10 + (buf[3] - '0');
|
||||
return g_strdup_printf (g_dpgettext2 (NULL, "OpenType layout", "Character Variant %d"), num);
|
||||
}
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (open_type_layout_features); i++)
|
||||
{
|
||||
if (tag == open_type_layout_features[i].tag)
|
||||
return g_strdup (g_dpgettext2 (NULL, "OpenType layout", open_type_layout_features[i].name));
|
||||
}
|
||||
|
||||
g_warning ("unknown OpenType layout feature tag: %s", buf);
|
||||
|
||||
return g_strdup (buf);
|
||||
}
|
||||
|
||||
static void
|
||||
update_feature_label (FontFeatures *self,
|
||||
FeatureItem *item,
|
||||
hb_font_t *hb_font,
|
||||
hb_tag_t script_tag,
|
||||
hb_tag_t lang_tag)
|
||||
{
|
||||
hb_face_t *hb_face;
|
||||
unsigned int script_index, lang_index, feature_index;
|
||||
hb_ot_name_id_t id;
|
||||
unsigned int len;
|
||||
char *label;
|
||||
char name[5] = { 0, };
|
||||
|
||||
hb_face = hb_font_get_face (hb_font);
|
||||
|
||||
hb_tag_to_string (item->tag, name);
|
||||
if (!is_ssNN (name) && !is_cvNN (name))
|
||||
return;
|
||||
|
||||
hb_ot_layout_table_find_script (hb_face, HB_OT_TAG_GSUB, script_tag, &script_index);
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
hb_ot_layout_script_find_language (hb_face, HB_OT_TAG_GSUB, script_index, lang_tag, &lang_index);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
if (hb_ot_layout_language_find_feature (hb_face, HB_OT_TAG_GSUB, script_index, lang_index, item->tag, &feature_index) &&
|
||||
hb_ot_layout_feature_get_name_ids (hb_face, HB_OT_TAG_GSUB, feature_index, &id, NULL, NULL, NULL, NULL))
|
||||
{
|
||||
len = hb_ot_name_get_utf8 (hb_face, id, HB_LANGUAGE_INVALID, NULL, NULL);
|
||||
len++;
|
||||
label = g_new (char, len);
|
||||
hb_ot_name_get_utf8 (hb_face, id, HB_LANGUAGE_INVALID, &len, label);
|
||||
|
||||
gtk_check_button_set_label (GTK_CHECK_BUTTON (item->feat), label);
|
||||
|
||||
g_free (label);
|
||||
}
|
||||
else
|
||||
{
|
||||
label = get_feature_display_name (item->tag);
|
||||
gtk_check_button_set_label (GTK_CHECK_BUTTON (item->feat), label);
|
||||
g_free (label);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_inconsistent (GtkCheckButton *button,
|
||||
gboolean inconsistent)
|
||||
{
|
||||
gtk_check_button_set_inconsistent (GTK_CHECK_BUTTON (button), inconsistent);
|
||||
gtk_widget_set_opacity (gtk_widget_get_first_child (GTK_WIDGET (button)), inconsistent ? 0.0 : 1.0);
|
||||
}
|
||||
|
||||
static void
|
||||
find_language_and_script (FontFeatures *self,
|
||||
hb_face_t *hb_face,
|
||||
hb_tag_t *lang_tag,
|
||||
hb_tag_t *script_tag)
|
||||
{
|
||||
int i, j, k;
|
||||
hb_tag_t scripts[80];
|
||||
unsigned int n_scripts;
|
||||
unsigned int count;
|
||||
hb_tag_t table[2] = { HB_OT_TAG_GSUB, HB_OT_TAG_GPOS };
|
||||
hb_language_t lang;
|
||||
const char *langname, *p;
|
||||
|
||||
langname = pango2_language_to_string (self->lang);
|
||||
|
||||
p = strchr (langname, '-');
|
||||
lang = hb_language_from_string (langname, p ? p - langname : -1);
|
||||
|
||||
n_scripts = 0;
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
count = G_N_ELEMENTS (scripts);
|
||||
hb_ot_layout_table_get_script_tags (hb_face, table[i], n_scripts, &count, scripts);
|
||||
n_scripts += count;
|
||||
}
|
||||
|
||||
for (j = 0; j < n_scripts; j++)
|
||||
{
|
||||
hb_tag_t languages[80];
|
||||
unsigned int n_languages;
|
||||
|
||||
n_languages = 0;
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
count = G_N_ELEMENTS (languages);
|
||||
hb_ot_layout_script_get_language_tags (hb_face, table[i], j, n_languages, &count, languages);
|
||||
n_languages += count;
|
||||
}
|
||||
|
||||
for (k = 0; k < n_languages; k++)
|
||||
{
|
||||
if (lang == hb_ot_tag_to_language (languages[k]))
|
||||
{
|
||||
*script_tag = scripts[j];
|
||||
*lang_tag = languages[k];
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*lang_tag = HB_OT_TAG_DEFAULT_LANGUAGE;
|
||||
*script_tag = HB_OT_TAG_DEFAULT_SCRIPT;
|
||||
}
|
||||
|
||||
static void
|
||||
hide_feature_maybe (FeatureItem *item,
|
||||
gboolean has_feature)
|
||||
{
|
||||
gtk_widget_set_visible (item->feat, has_feature);
|
||||
if (has_feature)
|
||||
gtk_widget_set_visible (gtk_widget_get_parent (item->feat), TRUE);
|
||||
}
|
||||
|
||||
/* Make features insensitive if the font/langsys does not have them,
|
||||
* and reset all others to their initial value
|
||||
*/
|
||||
static void
|
||||
update_features (FontFeatures *self)
|
||||
{
|
||||
guint script_index, lang_index;
|
||||
hb_tag_t lang_tag;
|
||||
hb_tag_t script_tag;
|
||||
Pango2Font *font;
|
||||
hb_font_t *hb_font;
|
||||
hb_face_t *hb_face;
|
||||
|
||||
font = get_font (self);
|
||||
hb_font = pango2_font_get_hb_font (font);
|
||||
hb_face = hb_font_get_face (hb_font);
|
||||
|
||||
{
|
||||
hb_tag_t table[2] = { HB_OT_TAG_GSUB, HB_OT_TAG_GPOS };
|
||||
hb_tag_t features[256];
|
||||
unsigned int count;
|
||||
unsigned int n_features = 0;
|
||||
|
||||
find_language_and_script (self, hb_face, &lang_tag, &script_tag);
|
||||
|
||||
/* Collect all features */
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
hb_ot_layout_table_find_script (hb_face,
|
||||
table[i],
|
||||
script_tag,
|
||||
&script_index);
|
||||
hb_ot_layout_script_select_language (hb_face,
|
||||
table[i],
|
||||
script_index,
|
||||
1,
|
||||
&lang_tag,
|
||||
&lang_index);
|
||||
|
||||
count = G_N_ELEMENTS (features);
|
||||
hb_ot_layout_language_get_feature_tags (hb_face,
|
||||
table[i],
|
||||
script_index,
|
||||
lang_index,
|
||||
n_features,
|
||||
&count,
|
||||
features);
|
||||
n_features += count;
|
||||
}
|
||||
|
||||
/* Update all the features */
|
||||
for (GList *l = self->feature_items; l; l = l->next)
|
||||
{
|
||||
FeatureItem *item = l->data;
|
||||
gboolean has_feature = FALSE;
|
||||
|
||||
for (int j = 0; j < n_features; j++)
|
||||
{
|
||||
if (item->tag == features[j])
|
||||
{
|
||||
has_feature = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
update_feature_label (self, item, hb_font, script_tag, lang_tag);
|
||||
|
||||
hide_feature_maybe (item, has_feature);
|
||||
|
||||
if (GTK_IS_CHECK_BUTTON (item->feat))
|
||||
{
|
||||
GtkWidget *def = GTK_WIDGET (g_object_get_data (G_OBJECT (item->feat), "default"));
|
||||
if (def)
|
||||
{
|
||||
gtk_widget_show (def);
|
||||
gtk_widget_show (gtk_widget_get_parent (def));
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (def), TRUE);
|
||||
}
|
||||
else
|
||||
set_inconsistent (GTK_CHECK_BUTTON (item->feat), TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Hide empty groups */
|
||||
for (GList *l = self->feature_items; l; l = l->next)
|
||||
{
|
||||
FeatureItem *item = l->data;
|
||||
GtkWidget *box;
|
||||
|
||||
box = gtk_widget_get_parent (item->feat);
|
||||
if (gtk_widget_get_visible (box))
|
||||
{
|
||||
GtkWidget *c;
|
||||
int count;
|
||||
|
||||
count = 0;
|
||||
for (c = gtk_widget_get_first_child (box); c; c = gtk_widget_get_next_sibling (c))
|
||||
{
|
||||
if (gtk_widget_get_visible (c))
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count == 1)
|
||||
gtk_widget_hide (box);
|
||||
else if (count == 2 &&
|
||||
item->tag == HB_TAG ('x', 'x', 'x', 'x'))
|
||||
gtk_widget_hide (box);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
script_changed (GtkComboBox *combo,
|
||||
FontFeatures *self)
|
||||
{
|
||||
update_features (self);
|
||||
}
|
||||
|
||||
static char *
|
||||
get_features (FontFeatures *self)
|
||||
{
|
||||
GString *s;
|
||||
char buf[128];
|
||||
|
||||
s = g_string_new ("");
|
||||
|
||||
for (GList *l = self->feature_items; l; l = l->next)
|
||||
{
|
||||
FeatureItem *item = l->data;
|
||||
|
||||
if (!gtk_widget_is_sensitive (item->feat))
|
||||
continue;
|
||||
|
||||
if (GTK_IS_CHECK_BUTTON (item->feat) && g_object_get_data (G_OBJECT (item->feat), "default"))
|
||||
{
|
||||
if (gtk_check_button_get_active (GTK_CHECK_BUTTON (item->feat)) &&
|
||||
item->tag != HB_TAG ('x', 'x', 'x', 'x'))
|
||||
{
|
||||
hb_feature_to_string (&(hb_feature_t) { item->tag, 1, 0, -1 }, buf, sizeof (buf));
|
||||
if (s->len > 0)
|
||||
g_string_append_c (s, ',');
|
||||
g_string_append (s, buf);
|
||||
}
|
||||
}
|
||||
else if (GTK_IS_CHECK_BUTTON (item->feat))
|
||||
{
|
||||
guint32 value;
|
||||
|
||||
if (gtk_check_button_get_inconsistent (GTK_CHECK_BUTTON (item->feat)))
|
||||
continue;
|
||||
|
||||
value = gtk_check_button_get_active (GTK_CHECK_BUTTON (item->feat));
|
||||
hb_feature_to_string (&(hb_feature_t) { item->tag, value, 0, -1 }, buf, sizeof (buf));
|
||||
if (s->len > 0)
|
||||
g_string_append_c (s, ',');
|
||||
g_string_append (s, buf);
|
||||
}
|
||||
}
|
||||
|
||||
return g_string_free (s, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
update_display (FontFeatures *self)
|
||||
{
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FEATURES]);
|
||||
g_simple_action_set_enabled (self->reset_action, TRUE);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
make_title_label (const char *title)
|
||||
{
|
||||
GtkWidget *label;
|
||||
|
||||
label = gtk_label_new (title);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
g_object_set (label, "margin-top", 10, "margin-bottom", 10, NULL);
|
||||
gtk_widget_add_css_class (label, "heading");
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
static void
|
||||
feat_toggled_cb (GtkCheckButton *check_button,
|
||||
gpointer data)
|
||||
{
|
||||
set_inconsistent (check_button, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
feat_pressed (GtkGestureClick *gesture,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
GtkWidget *feat)
|
||||
{
|
||||
const guint button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
|
||||
|
||||
if (button == GDK_BUTTON_PRIMARY)
|
||||
{
|
||||
g_signal_handlers_block_by_func (feat, feat_pressed, NULL);
|
||||
|
||||
if (gtk_check_button_get_inconsistent (GTK_CHECK_BUTTON (feat)))
|
||||
{
|
||||
set_inconsistent (GTK_CHECK_BUTTON (feat), FALSE);
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (feat), TRUE);
|
||||
}
|
||||
|
||||
g_signal_handlers_unblock_by_func (feat, feat_pressed, NULL);
|
||||
}
|
||||
else if (button == GDK_BUTTON_SECONDARY)
|
||||
{
|
||||
gboolean inconsistent = gtk_check_button_get_inconsistent (GTK_CHECK_BUTTON (feat));
|
||||
set_inconsistent (GTK_CHECK_BUTTON (feat), !inconsistent);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_check_group (FontFeatures *self,
|
||||
const char *title,
|
||||
const char **tags,
|
||||
unsigned int n_tags,
|
||||
int row)
|
||||
{
|
||||
GtkWidget *group;
|
||||
int i;
|
||||
|
||||
group = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_widget_set_halign (group, GTK_ALIGN_START);
|
||||
|
||||
gtk_box_append (GTK_BOX (group), make_title_label (title));
|
||||
|
||||
for (i = 0; i < n_tags; i++)
|
||||
{
|
||||
unsigned int tag;
|
||||
GtkWidget *feat;
|
||||
FeatureItem *item;
|
||||
GtkGesture *gesture;
|
||||
char *name;
|
||||
|
||||
tag = hb_tag_from_string (tags[i], -1);
|
||||
|
||||
name = get_feature_display_name (tag);
|
||||
feat = gtk_check_button_new_with_label (name);
|
||||
g_free (name);
|
||||
set_inconsistent (GTK_CHECK_BUTTON (feat), TRUE);
|
||||
g_signal_connect_swapped (feat, "notify::active", G_CALLBACK (update_display), self);
|
||||
g_signal_connect_swapped (feat, "notify::inconsistent", G_CALLBACK (update_display), self);
|
||||
g_signal_connect (feat, "toggled", G_CALLBACK (feat_toggled_cb), NULL);
|
||||
|
||||
gesture = gtk_gesture_click_new ();
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
|
||||
g_signal_connect (gesture, "pressed", G_CALLBACK (feat_pressed), feat);
|
||||
gtk_widget_add_controller (feat, GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
gtk_box_append (GTK_BOX (group), feat);
|
||||
|
||||
item = g_new (FeatureItem, 1);
|
||||
item->name = tags[i];
|
||||
item->tag = tag;
|
||||
item->feat = feat;
|
||||
|
||||
self->feature_items = g_list_prepend (self->feature_items, item);
|
||||
}
|
||||
|
||||
gtk_grid_attach (self->grid, group, 0, row, 2, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
add_radio_group (FontFeatures *self,
|
||||
const char *title,
|
||||
const char **tags,
|
||||
unsigned int n_tags,
|
||||
int row)
|
||||
{
|
||||
GtkWidget *group;
|
||||
int i;
|
||||
GtkWidget *group_button = NULL;
|
||||
|
||||
group = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_widget_set_halign (group, GTK_ALIGN_START);
|
||||
|
||||
gtk_box_append (GTK_BOX (group), make_title_label (title));
|
||||
|
||||
for (i = 0; i < n_tags; i++)
|
||||
{
|
||||
unsigned int tag;
|
||||
GtkWidget *feat;
|
||||
FeatureItem *item;
|
||||
char *name;
|
||||
|
||||
tag = hb_tag_from_string (tags[i], -1);
|
||||
name = get_feature_display_name (tag);
|
||||
feat = gtk_check_button_new_with_label (name ? name : _("Default"));
|
||||
g_free (name);
|
||||
if (group_button == NULL)
|
||||
group_button = feat;
|
||||
else
|
||||
gtk_check_button_set_group (GTK_CHECK_BUTTON (feat), GTK_CHECK_BUTTON (group_button));
|
||||
g_signal_connect_swapped (feat, "notify::active", G_CALLBACK (update_display), self);
|
||||
g_object_set_data (G_OBJECT (feat), "default", group_button);
|
||||
|
||||
gtk_box_append (GTK_BOX (group), feat);
|
||||
|
||||
item = g_new (FeatureItem, 1);
|
||||
item->name = tags[i];
|
||||
item->tag = tag;
|
||||
item->feat = feat;
|
||||
|
||||
self->feature_items = g_list_prepend (self->feature_items, item);
|
||||
}
|
||||
|
||||
gtk_grid_attach (self->grid, group, 0, row, 2, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_features (FontFeatures *self)
|
||||
{
|
||||
const char *kerning[] = { "kern" };
|
||||
const char *ligatures[] = { "liga", "dlig", "hlig", "clig", "rlig" };
|
||||
const char *letter_case[] = {
|
||||
"smcp", "c2sc", "pcap", "c2pc", "unic", "cpsp", "case"
|
||||
};
|
||||
const char *number_case[] = { "xxxx", "lnum", "onum" };
|
||||
const char *number_spacing[] = { "xxxx", "pnum", "tnum" };
|
||||
const char *fractions[] = { "xxxx", "frac", "afrc" };
|
||||
const char *num_extras[] = { "zero", "nalt", "sinf" };
|
||||
const char *char_alt[] = {
|
||||
"swsh", "cswh", "locl", "calt", "falt", "hist",
|
||||
"salt", "jalt", "titl", "rand", "subs", "sups",
|
||||
"ordn", "ltra", "ltrm", "rtla", "rtlm", "rclt"
|
||||
};
|
||||
const char *pos_alt[] = {
|
||||
"init", "medi", "med2", "fina", "fin2", "fin3", "isol"
|
||||
};
|
||||
const char *width_var[] = {
|
||||
"fwid", "hwid", "halt", "pwid", "palt", "twid", "qwid"
|
||||
};
|
||||
const char *style_alt[] = {
|
||||
"ss01", "ss02", "ss03", "ss04", "ss05", "ss06",
|
||||
"ss07", "ss08", "ss09", "ss10", "ss11", "ss12",
|
||||
"ss13", "ss14", "ss15", "ss16", "ss17", "ss18",
|
||||
"ss19", "ss20"
|
||||
};
|
||||
const char *char_var[] = {
|
||||
"cv01", "cv02", "cv03", "cv04", "cv05", "cv06",
|
||||
"cv07", "cv08", "cv09", "cv10", "cv11", "cv12",
|
||||
"cv13", "cv14", "cv15", "cv16", "cv17", "cv18",
|
||||
"cv19", "cv20"
|
||||
};
|
||||
const char *math[] = { "dtls", "flac", "mgrk", "ssty" };
|
||||
const char *bounds[] = { "opbd", "lfbd", "rtbd" };
|
||||
int row = 0;
|
||||
|
||||
add_check_group (self, _("Kerning"), kerning, G_N_ELEMENTS (kerning), row++);
|
||||
add_check_group (self, _("Ligatures"), ligatures, G_N_ELEMENTS (ligatures), row++);
|
||||
add_check_group (self, _("Letter Case"), letter_case, G_N_ELEMENTS (letter_case), row++);
|
||||
add_radio_group (self, _("Number Case"), number_case, G_N_ELEMENTS (number_case), row++);
|
||||
add_radio_group (self, _("Number Spacing"), number_spacing, G_N_ELEMENTS (number_spacing), row++);
|
||||
add_radio_group (self, _("Fractions"), fractions, G_N_ELEMENTS (fractions), row++);
|
||||
add_check_group (self, _("Numeric Extras"), num_extras, G_N_ELEMENTS (num_extras), row++);
|
||||
add_check_group (self, _("Character Alternatives"), char_alt, G_N_ELEMENTS (char_alt), row++);
|
||||
add_check_group (self, _("Positional Alternatives"), pos_alt, G_N_ELEMENTS (pos_alt), row++);
|
||||
add_check_group (self, _("Width Variants"), width_var, G_N_ELEMENTS (width_var), row++);
|
||||
add_check_group (self, _("Alternative Stylistic Sets"), style_alt, G_N_ELEMENTS (style_alt), row++);
|
||||
add_check_group (self, _("Character Variants"), char_var, G_N_ELEMENTS (char_var), row++);
|
||||
add_check_group (self, _("Mathematical"), math, G_N_ELEMENTS (math), row++);
|
||||
add_check_group (self, _("Optical Bounds"), bounds, G_N_ELEMENTS (bounds), row++);
|
||||
|
||||
self->feature_items = g_list_reverse (self->feature_items);
|
||||
}
|
||||
|
||||
static void
|
||||
reset (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
FontFeatures *self)
|
||||
{
|
||||
update_features (self);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FEATURES]);
|
||||
g_simple_action_set_enabled (self->reset_action, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
font_features_init (FontFeatures *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
self->font_desc = pango2_font_description_from_string ("sans 12");
|
||||
self->lang = pango2_language_get_default ();
|
||||
|
||||
setup_features (self);
|
||||
|
||||
self->reset_action = g_simple_action_new ("reset", NULL);
|
||||
g_simple_action_set_enabled (self->reset_action, FALSE);
|
||||
g_signal_connect (self->reset_action, "activate", G_CALLBACK (reset), self);
|
||||
}
|
||||
|
||||
static void
|
||||
font_features_dispose (GObject *object)
|
||||
{
|
||||
FontFeatures *self = FONT_FEATURES (object);
|
||||
|
||||
gtk_widget_clear_template (GTK_WIDGET (object), FONT_FEATURES_TYPE);
|
||||
|
||||
g_list_free_full (self->feature_items, g_free);
|
||||
|
||||
G_OBJECT_CLASS (font_features_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
font_features_finalize (GObject *object)
|
||||
{
|
||||
FontFeatures *self = FONT_FEATURES (object);
|
||||
|
||||
g_clear_pointer (&self->font_desc, pango2_font_description_free);
|
||||
|
||||
G_OBJECT_CLASS (font_features_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
font_features_set_property (GObject *object,
|
||||
unsigned int prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
FontFeatures *self = FONT_FEATURES (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FONT_DESC:
|
||||
pango2_font_description_free (self->font_desc);
|
||||
self->font_desc = pango2_font_description_copy (g_value_get_boxed (value));
|
||||
update_features (self);
|
||||
break;
|
||||
|
||||
case PROP_LANGUAGE:
|
||||
self->lang = pango2_language_from_string (g_value_get_string (value));
|
||||
update_features (self);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
font_features_get_property (GObject *object,
|
||||
unsigned int prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
FontFeatures *self = FONT_FEATURES (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FEATURES:
|
||||
g_value_take_string (value, get_features (self));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
font_features_class_init (FontFeaturesClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->dispose = font_features_dispose;
|
||||
object_class->finalize = font_features_finalize;
|
||||
object_class->get_property = font_features_get_property;
|
||||
object_class->set_property = font_features_set_property;
|
||||
|
||||
properties[PROP_FONT_DESC] =
|
||||
g_param_spec_boxed ("font-desc", "", "",
|
||||
PANGO2_TYPE_FONT_DESCRIPTION,
|
||||
G_PARAM_WRITABLE);
|
||||
|
||||
properties[PROP_LANGUAGE] =
|
||||
g_param_spec_string ("language", "", "",
|
||||
"en",
|
||||
G_PARAM_WRITABLE);
|
||||
|
||||
properties[PROP_FEATURES] =
|
||||
g_param_spec_string ("features", "", "",
|
||||
"",
|
||||
G_PARAM_READABLE);
|
||||
|
||||
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/fontexplorer/fontfeatures.ui");
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontFeatures, grid);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontFeatures, label);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), script_changed);
|
||||
|
||||
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "fontfeatures");
|
||||
}
|
||||
|
||||
FontFeatures *
|
||||
font_features_new (void)
|
||||
{
|
||||
return g_object_new (FONT_FEATURES_TYPE, NULL);
|
||||
}
|
||||
|
||||
GAction *
|
||||
font_features_get_reset_action (FontFeatures *self)
|
||||
{
|
||||
return G_ACTION (self->reset_action);
|
||||
}
|
||||
16
demos/font-explorer/fontfeatures.h
Normal file
16
demos/font-explorer/fontfeatures.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define FONT_FEATURES_TYPE (font_features_get_type ())
|
||||
#define FONT_FEATURES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_FEATURES_TYPE, FontFeatures))
|
||||
|
||||
|
||||
typedef struct _FontFeatures FontFeatures;
|
||||
typedef struct _FontFeaturesClass FontFeaturesClass;
|
||||
|
||||
|
||||
GType font_features_get_type (void);
|
||||
FontFeatures * font_features_new (void);
|
||||
GAction * font_features_get_reset_action (FontFeatures *self);
|
||||
25
demos/font-explorer/fontfeatures.ui
Normal file
25
demos/font-explorer/fontfeatures.ui
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="FontFeatures" parent="GtkWidget">
|
||||
<property name="layout-manager"><object class="GtkBinLayout"/></property>
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid">
|
||||
<child>
|
||||
<object class="GtkLabel" id="label">
|
||||
<property name="label" translatable="yes">Features</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="heading"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="row">-1</property>
|
||||
<property name="column">0</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
488
demos/font-explorer/fontvariations.c
Normal file
488
demos/font-explorer/fontvariations.c
Normal file
@@ -0,0 +1,488 @@
|
||||
#include "fontvariations.h"
|
||||
#include "rangeedit.h"
|
||||
#include <gtk/gtk.h>
|
||||
#include <hb-ot.h>
|
||||
|
||||
enum {
|
||||
PROP_FONT_DESC = 1,
|
||||
PROP_VARIATIONS,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
struct _FontVariations
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
GtkGrid *label;
|
||||
GtkGrid *grid;
|
||||
Pango2FontDescription *font_desc;
|
||||
GSimpleAction *reset_action;
|
||||
gboolean has_variations;
|
||||
|
||||
GtkWidget *instance_combo;
|
||||
GHashTable *axes;
|
||||
GHashTable *instances;
|
||||
};
|
||||
|
||||
struct _FontVariationsClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FontVariations, font_variations, GTK_TYPE_WIDGET);
|
||||
|
||||
static Pango2Font *
|
||||
get_font (FontVariations *self)
|
||||
{
|
||||
Pango2Context *context;
|
||||
|
||||
context = gtk_widget_get_pango_context (GTK_WIDGET (self));
|
||||
return pango2_context_load_font (context, self->font_desc);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
guint32 tag;
|
||||
GtkAdjustment *adjustment;
|
||||
double default_value;
|
||||
} Axis;
|
||||
|
||||
static guint
|
||||
axes_hash (gconstpointer v)
|
||||
{
|
||||
const Axis *p = v;
|
||||
|
||||
return p->tag;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
axes_equal (gconstpointer v1, gconstpointer v2)
|
||||
{
|
||||
const Axis *p1 = v1;
|
||||
const Axis *p2 = v2;
|
||||
|
||||
return p1->tag == p2->tag;
|
||||
}
|
||||
|
||||
static void
|
||||
unset_instance (GtkAdjustment *adjustment,
|
||||
FontVariations *self)
|
||||
{
|
||||
if (self->instance_combo)
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (self->instance_combo), 0);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_VARIATIONS]);
|
||||
g_simple_action_set_enabled (self->reset_action, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
add_axis (FontVariations *self,
|
||||
hb_face_t *hb_face,
|
||||
hb_ot_var_axis_info_t *ax,
|
||||
int i)
|
||||
{
|
||||
GtkWidget *axis_label;
|
||||
GtkWidget *axis_scale;
|
||||
GtkAdjustment *adjustment;
|
||||
Axis *axis;
|
||||
char name[20];
|
||||
unsigned int name_len = 20;
|
||||
|
||||
hb_ot_name_get_utf8 (hb_face, ax->name_id, HB_LANGUAGE_INVALID, &name_len, name);
|
||||
|
||||
axis_label = gtk_label_new (name);
|
||||
gtk_widget_set_halign (axis_label, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (axis_label, GTK_ALIGN_BASELINE);
|
||||
gtk_grid_attach (self->grid, axis_label, 0, i, 1, 1);
|
||||
adjustment = gtk_adjustment_new (ax->default_value, ax->min_value, ax->max_value,
|
||||
1.0, 10.0, 0.0);
|
||||
axis_scale = g_object_new (RANGE_EDIT_TYPE,
|
||||
"adjustment", adjustment,
|
||||
"default-value", ax->default_value,
|
||||
"n-chars", 5,
|
||||
"hexpand", TRUE,
|
||||
"halign", GTK_ALIGN_FILL,
|
||||
"valign", GTK_ALIGN_BASELINE,
|
||||
NULL);
|
||||
gtk_grid_attach (self->grid, axis_scale, 1, i, 1, 1);
|
||||
|
||||
axis = g_new0 (Axis, 1);
|
||||
axis->tag = ax->tag;
|
||||
axis->adjustment = adjustment;
|
||||
axis->default_value = ax->default_value;
|
||||
g_hash_table_add (self->axes, axis);
|
||||
|
||||
g_signal_connect (adjustment, "value-changed", G_CALLBACK (unset_instance), self);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
unsigned int index;
|
||||
} Instance;
|
||||
|
||||
static guint
|
||||
instance_hash (gconstpointer v)
|
||||
{
|
||||
const Instance *p = v;
|
||||
|
||||
return g_str_hash (p->name);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
instance_equal (gconstpointer v1, gconstpointer v2)
|
||||
{
|
||||
const Instance *p1 = v1;
|
||||
const Instance *p2 = v2;
|
||||
|
||||
return g_str_equal (p1->name, p2->name);
|
||||
}
|
||||
|
||||
static void
|
||||
free_instance (gpointer data)
|
||||
{
|
||||
Instance *instance = data;
|
||||
|
||||
g_free (instance->name);
|
||||
g_free (instance);
|
||||
}
|
||||
|
||||
static void
|
||||
add_instance (FontVariations *self,
|
||||
hb_face_t *face,
|
||||
unsigned int index,
|
||||
GtkWidget *combo,
|
||||
int pos)
|
||||
{
|
||||
Instance *instance;
|
||||
hb_ot_name_id_t name_id;
|
||||
char name[20];
|
||||
unsigned int name_len = 20;
|
||||
|
||||
instance = g_new0 (Instance, 1);
|
||||
|
||||
name_id = hb_ot_var_named_instance_get_subfamily_name_id (face, index);
|
||||
hb_ot_name_get_utf8 (face, name_id, HB_LANGUAGE_INVALID, &name_len, name);
|
||||
|
||||
instance->name = g_strdup (name);
|
||||
instance->index = index;
|
||||
|
||||
g_hash_table_add (self->instances, instance);
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), instance->name);
|
||||
}
|
||||
|
||||
static void
|
||||
instance_changed (GtkComboBox *combo,
|
||||
FontVariations *self)
|
||||
{
|
||||
char *text;
|
||||
Instance *instance;
|
||||
Instance ikey;
|
||||
int i;
|
||||
unsigned int coords_length;
|
||||
float *coords = NULL;
|
||||
hb_ot_var_axis_info_t *ai = NULL;
|
||||
unsigned int n_axes;
|
||||
Pango2Font *font = NULL;
|
||||
hb_font_t *hb_font;
|
||||
hb_face_t *hb_face;
|
||||
|
||||
text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (combo));
|
||||
if (text[0] == '\0')
|
||||
goto out;
|
||||
|
||||
ikey.name = text;
|
||||
instance = g_hash_table_lookup (self->instances, &ikey);
|
||||
if (!instance)
|
||||
{
|
||||
g_print ("did not find instance %s\n", text);
|
||||
goto out;
|
||||
}
|
||||
|
||||
font = get_font (self);
|
||||
hb_font = pango2_font_get_hb_font (font);
|
||||
hb_face = hb_font_get_face (hb_font);
|
||||
|
||||
n_axes = hb_ot_var_get_axis_infos (hb_face, 0, NULL, NULL);
|
||||
ai = g_new (hb_ot_var_axis_info_t, n_axes);
|
||||
hb_ot_var_get_axis_infos (hb_face, 0, &n_axes, ai);
|
||||
|
||||
coords = g_new (float, n_axes);
|
||||
hb_ot_var_named_instance_get_design_coords (hb_face,
|
||||
instance->index,
|
||||
&coords_length,
|
||||
coords);
|
||||
|
||||
for (i = 0; i < n_axes; i++)
|
||||
{
|
||||
Axis *axis;
|
||||
Axis akey;
|
||||
double value;
|
||||
|
||||
value = coords[ai[i].axis_index];
|
||||
|
||||
akey.tag = ai[i].tag;
|
||||
axis = g_hash_table_lookup (self->axes, &akey);
|
||||
if (axis)
|
||||
{
|
||||
g_signal_handlers_block_by_func (axis->adjustment, unset_instance, self);
|
||||
gtk_adjustment_set_value (axis->adjustment, value);
|
||||
g_signal_handlers_unblock_by_func (axis->adjustment, unset_instance, self);
|
||||
}
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_VARIATIONS]);
|
||||
g_simple_action_set_enabled (self->reset_action, TRUE);
|
||||
|
||||
out:
|
||||
g_free (text);
|
||||
g_clear_object (&font);
|
||||
g_free (ai);
|
||||
g_free (coords);
|
||||
}
|
||||
|
||||
static void
|
||||
update_variations (FontVariations *self)
|
||||
{
|
||||
GtkWidget *child;
|
||||
Pango2Font *font;
|
||||
hb_font_t *hb_font;
|
||||
hb_face_t *hb_face;
|
||||
unsigned int n_axes;
|
||||
hb_ot_var_axis_info_t *ai = NULL;
|
||||
int i;
|
||||
|
||||
font = get_font (self);
|
||||
hb_font = pango2_font_get_hb_font (font);
|
||||
hb_face = hb_font_get_face (hb_font);
|
||||
|
||||
g_object_ref (self->label);
|
||||
|
||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (self->grid))))
|
||||
gtk_grid_remove (self->grid, child);
|
||||
|
||||
gtk_grid_attach (self->grid, GTK_WIDGET (self->label), 0, -2, 2, 1);
|
||||
g_object_unref (self->label);
|
||||
|
||||
self->instance_combo = NULL;
|
||||
g_hash_table_remove_all (self->axes);
|
||||
g_hash_table_remove_all (self->instances);
|
||||
|
||||
n_axes = hb_ot_var_get_axis_infos (hb_face, 0, NULL, NULL);
|
||||
self->has_variations = n_axes > 0;
|
||||
gtk_widget_set_visible (GTK_WIDGET (self), self->has_variations);
|
||||
if (!self->has_variations)
|
||||
{
|
||||
g_simple_action_set_enabled (self->reset_action, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (hb_ot_var_get_named_instance_count (hb_face) > 0)
|
||||
{
|
||||
GtkWidget *label;
|
||||
GtkWidget *combo;
|
||||
|
||||
label = gtk_label_new ("Instance");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
|
||||
gtk_grid_attach (self->grid, label, 0, -1, 1, 1);
|
||||
|
||||
combo = gtk_combo_box_text_new ();
|
||||
gtk_widget_set_halign (combo, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (combo, GTK_ALIGN_BASELINE);
|
||||
gtk_widget_set_hexpand (combo, TRUE);
|
||||
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "");
|
||||
|
||||
for (i = 0; i < hb_ot_var_get_named_instance_count (hb_face); i++)
|
||||
add_instance (self, hb_face, i, combo, i);
|
||||
|
||||
gtk_grid_attach (GTK_GRID (self->grid), combo, 1, -1, 1, 1);
|
||||
g_signal_connect (combo, "changed", G_CALLBACK (instance_changed), self);
|
||||
self->instance_combo = combo;
|
||||
}
|
||||
|
||||
ai = g_new (hb_ot_var_axis_info_t, n_axes);
|
||||
hb_ot_var_get_axis_infos (hb_face, 0, &n_axes, ai);
|
||||
for (i = 0; i < n_axes; i++)
|
||||
add_axis (self, hb_face, &ai[i], i);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_VARIATIONS]);
|
||||
|
||||
g_clear_object (&font);
|
||||
g_free (ai);
|
||||
}
|
||||
|
||||
static char *
|
||||
get_variations (FontVariations *self)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
Axis *axis;
|
||||
char buf[G_ASCII_DTOSTR_BUF_SIZE];
|
||||
const char *sep = "";
|
||||
GString *s;
|
||||
|
||||
if (!self->has_variations)
|
||||
return g_strdup ("");
|
||||
|
||||
s = g_string_new ("");
|
||||
|
||||
g_hash_table_iter_init (&iter, self->axes);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)NULL, (gpointer *)&axis))
|
||||
{
|
||||
char tag[5];
|
||||
double value;
|
||||
|
||||
hb_tag_to_string (axis->tag, tag);
|
||||
tag[4] = '\0';
|
||||
value = gtk_adjustment_get_value (axis->adjustment);
|
||||
|
||||
g_string_append_printf (s, "%s%s=%s", sep, tag, g_ascii_dtostr (buf, sizeof (buf), value));
|
||||
sep = ",";
|
||||
}
|
||||
|
||||
return g_string_free (s, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
reset (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
FontVariations *self)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
Axis *axis;
|
||||
|
||||
if (self->instance_combo)
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (self->instance_combo), 0);
|
||||
|
||||
g_hash_table_iter_init (&iter, self->axes);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)NULL, (gpointer *)&axis))
|
||||
{
|
||||
g_signal_handlers_block_by_func (axis->adjustment, unset_instance, self);
|
||||
gtk_adjustment_set_value (axis->adjustment, axis->default_value);
|
||||
g_signal_handlers_unblock_by_func (axis->adjustment, unset_instance, self);
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_VARIATIONS]);
|
||||
g_simple_action_set_enabled (self->reset_action, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
font_variations_init (FontVariations *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
self->reset_action = g_simple_action_new ("reset", NULL);
|
||||
g_simple_action_set_enabled (self->reset_action, FALSE);
|
||||
g_signal_connect (self->reset_action, "activate", G_CALLBACK (reset), self);
|
||||
|
||||
self->instances = g_hash_table_new_full (instance_hash, instance_equal,
|
||||
NULL, free_instance);
|
||||
self->axes = g_hash_table_new_full (axes_hash, axes_equal,
|
||||
NULL, g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
font_variations_dispose (GObject *object)
|
||||
{
|
||||
FontVariations *self = FONT_VARIATIONS (object);
|
||||
|
||||
gtk_widget_clear_template (GTK_WIDGET (object), FONT_VARIATIONS_TYPE);
|
||||
|
||||
g_hash_table_unref (self->instances);
|
||||
g_hash_table_unref (self->axes);
|
||||
|
||||
G_OBJECT_CLASS (font_variations_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
font_variations_finalize (GObject *object)
|
||||
{
|
||||
FontVariations *self = FONT_VARIATIONS (object);
|
||||
|
||||
g_clear_pointer (&self->font_desc, pango2_font_description_free);
|
||||
|
||||
G_OBJECT_CLASS (font_variations_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
font_variations_set_property (GObject *object,
|
||||
unsigned int prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
FontVariations *self = FONT_VARIATIONS (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FONT_DESC:
|
||||
pango2_font_description_free (self->font_desc);
|
||||
self->font_desc = pango2_font_description_copy (g_value_get_boxed (value));
|
||||
update_variations (self);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
font_variations_get_property (GObject *object,
|
||||
unsigned int prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
FontVariations *self = FONT_VARIATIONS (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_VARIATIONS:
|
||||
g_value_take_string (value, get_variations (self));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
font_variations_class_init (FontVariationsClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->dispose = font_variations_dispose;
|
||||
object_class->finalize = font_variations_finalize;
|
||||
object_class->get_property = font_variations_get_property;
|
||||
object_class->set_property = font_variations_set_property;
|
||||
|
||||
properties[PROP_FONT_DESC] =
|
||||
g_param_spec_boxed ("font-desc", "", "",
|
||||
PANGO2_TYPE_FONT_DESCRIPTION,
|
||||
G_PARAM_WRITABLE);
|
||||
|
||||
properties[PROP_VARIATIONS] =
|
||||
g_param_spec_string ("variations", "", "",
|
||||
"",
|
||||
G_PARAM_READABLE);
|
||||
|
||||
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/fontexplorer/fontvariations.ui");
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontVariations, grid);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontVariations, label);
|
||||
|
||||
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "fontvariations");
|
||||
}
|
||||
|
||||
FontVariations *
|
||||
font_variations_new (void)
|
||||
{
|
||||
return g_object_new (FONT_VARIATIONS_TYPE, NULL);
|
||||
}
|
||||
|
||||
GAction *
|
||||
font_variations_get_reset_action (FontVariations *self)
|
||||
{
|
||||
return G_ACTION (self->reset_action);
|
||||
}
|
||||
16
demos/font-explorer/fontvariations.h
Normal file
16
demos/font-explorer/fontvariations.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define FONT_VARIATIONS_TYPE (font_variations_get_type ())
|
||||
#define FONT_VARIATIONS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_VARIATIONS_TYPE, FontVariations))
|
||||
|
||||
|
||||
typedef struct _FontVariations FontVariations;
|
||||
typedef struct _FontVariationsClass FontVariationsClass;
|
||||
|
||||
|
||||
GType font_variations_get_type (void);
|
||||
FontVariations * font_variations_new (void);
|
||||
GAction * font_variations_get_reset_action (FontVariations *self);
|
||||
25
demos/font-explorer/fontvariations.ui
Normal file
25
demos/font-explorer/fontvariations.ui
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="FontVariations" parent="GtkWidget">
|
||||
<property name="layout-manager"><object class="GtkBinLayout"/></property>
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid">
|
||||
<child>
|
||||
<object class="GtkLabel" id="label">
|
||||
<property name="label" translatable="yes">Variations</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="heading"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="row">-2</property>
|
||||
<property name="column">0</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
413
demos/font-explorer/fontview.c
Normal file
413
demos/font-explorer/fontview.c
Normal file
@@ -0,0 +1,413 @@
|
||||
#include "fontview.h"
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
enum {
|
||||
PROP_FONT_DESC = 1,
|
||||
PROP_SIZE,
|
||||
PROP_LETTERSPACING,
|
||||
PROP_LINE_HEIGHT,
|
||||
PROP_FOREGROUND,
|
||||
PROP_BACKGROUND,
|
||||
PROP_VARIATIONS,
|
||||
PROP_FEATURES,
|
||||
PROP_PALETTE,
|
||||
PROP_SAMPLE_TEXT,
|
||||
PROP_IGNORE_SIZE,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
struct _FontView
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
GtkStack *stack;
|
||||
GtkTextView *edit;
|
||||
GtkLabel *content;
|
||||
GtkScrolledWindow *swin;
|
||||
|
||||
Pango2FontDescription *font_desc;
|
||||
float size;
|
||||
char *variations;
|
||||
char *features;
|
||||
char *palette;
|
||||
int letterspacing;
|
||||
float line_height;
|
||||
GdkRGBA foreground;
|
||||
GdkRGBA background;
|
||||
GtkCssProvider *bg_provider;
|
||||
char *sample_text;
|
||||
gboolean do_waterfall;
|
||||
};
|
||||
|
||||
struct _FontViewClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FontView, font_view, GTK_TYPE_WIDGET);
|
||||
|
||||
static void
|
||||
font_view_init (FontView *self)
|
||||
{
|
||||
self->font_desc = pango2_font_description_from_string ("sans 12");
|
||||
self->size = 12.;
|
||||
self->letterspacing = 0;
|
||||
self->line_height = 1.;
|
||||
self->variations = g_strdup ("");
|
||||
self->features = g_strdup ("");
|
||||
self->palette = g_strdup (PANGO2_COLOR_PALETTE_DEFAULT);
|
||||
self->foreground = (GdkRGBA){0., 0., 0., 1. };
|
||||
self->background = (GdkRGBA){1., 1., 1., 1. };
|
||||
self->sample_text = g_strdup ("Some sample text is better than other sample text");
|
||||
|
||||
gtk_widget_set_layout_manager (GTK_WIDGET (self),
|
||||
gtk_box_layout_new (GTK_ORIENTATION_VERTICAL));
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
self->bg_provider = gtk_css_provider_new ();
|
||||
gtk_style_context_add_provider (gtk_widget_get_style_context (GTK_WIDGET (self->content)),
|
||||
GTK_STYLE_PROVIDER (self->bg_provider), 800);
|
||||
}
|
||||
|
||||
static void
|
||||
font_view_dispose (GObject *object)
|
||||
{
|
||||
gtk_widget_clear_template (GTK_WIDGET (object), FONT_VIEW_TYPE);
|
||||
|
||||
G_OBJECT_CLASS (font_view_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
font_view_finalize (GObject *object)
|
||||
{
|
||||
FontView *self = FONT_VIEW (object);
|
||||
|
||||
pango2_font_description_free (self->font_desc);
|
||||
g_free (self->variations);
|
||||
g_free (self->features);
|
||||
g_free (self->palette);
|
||||
|
||||
G_OBJECT_CLASS (font_view_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
update_view (FontView *self)
|
||||
{
|
||||
Pango2FontDescription *desc;
|
||||
Pango2AttrList *attrs;
|
||||
char *fg, *bg, *css;
|
||||
|
||||
desc = pango2_font_description_copy_static (self->font_desc);
|
||||
pango2_font_description_set_size (desc, 12 * PANGO2_SCALE);
|
||||
pango2_font_description_set_variations (desc, self->variations);
|
||||
|
||||
attrs = pango2_attr_list_new ();
|
||||
pango2_attr_list_insert (attrs, pango2_attr_font_desc_new (desc));
|
||||
pango2_attr_list_insert (attrs, pango2_attr_size_new (self->size * PANGO2_SCALE));
|
||||
pango2_attr_list_insert (attrs, pango2_attr_letter_spacing_new (self->letterspacing));
|
||||
pango2_attr_list_insert (attrs, pango2_attr_line_height_new (self->line_height));
|
||||
pango2_attr_list_insert (attrs, pango2_attr_foreground_new (&(Pango2Color){65535 * self->foreground.red,
|
||||
65535 * self->foreground.green,
|
||||
65535 * self->foreground.blue,
|
||||
65535 * self->foreground.alpha}));
|
||||
pango2_attr_list_insert (attrs, pango2_attr_font_features_new (self->features));
|
||||
pango2_attr_list_insert (attrs, pango2_attr_palette_new (self->palette));
|
||||
|
||||
pango2_font_description_free (desc);
|
||||
|
||||
gtk_scrolled_window_set_policy (self->swin,
|
||||
self->do_waterfall ? GTK_POLICY_AUTOMATIC : GTK_POLICY_NEVER,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_label_set_wrap (self->content, !self->do_waterfall);
|
||||
|
||||
if (self->do_waterfall)
|
||||
{
|
||||
GString *str;
|
||||
int sizes[] = { 7, 8, 9, 10, 12, 14, 16, 20, 24, 30, 40, 50, 60, 70, 90 };
|
||||
int start, text_len;
|
||||
|
||||
str = g_string_new ("");
|
||||
start = 0;
|
||||
text_len = strlen (self->sample_text);
|
||||
for (int i = 0; i < G_N_ELEMENTS (sizes); i++)
|
||||
{
|
||||
Pango2Attribute *attr;
|
||||
|
||||
g_string_append (str, self->sample_text);
|
||||
g_string_append (str, "
"); /* Unicode line separator */
|
||||
|
||||
attr = pango2_attr_size_new (sizes[i] * PANGO2_SCALE);
|
||||
pango2_attribute_set_range (attr, start, start + text_len);
|
||||
pango2_attr_list_insert (attrs, attr);
|
||||
start += text_len + strlen ("
");
|
||||
}
|
||||
gtk_label_set_text (self->content, str->str);
|
||||
gtk_label_set_attributes (self->content, attrs);
|
||||
g_string_free (str, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_label_set_label (self->content, self->sample_text);
|
||||
gtk_label_set_attributes (self->content, attrs);
|
||||
}
|
||||
|
||||
pango2_attr_list_unref (attrs);
|
||||
|
||||
fg = gdk_rgba_to_string (&self->foreground);
|
||||
bg = gdk_rgba_to_string (&self->background);
|
||||
css = g_strdup_printf (".view_background { caret-color: %s; background-color: %s; }", fg, bg);
|
||||
gtk_css_provider_load_from_data (self->bg_provider, css, strlen (css));
|
||||
g_free (css);
|
||||
g_free (fg);
|
||||
g_free (bg);
|
||||
}
|
||||
|
||||
static void
|
||||
toggle_edit (GtkToggleButton *button,
|
||||
FontView *self)
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
|
||||
buffer = gtk_text_view_get_buffer (self->edit);
|
||||
|
||||
if (gtk_toggle_button_get_active (button))
|
||||
{
|
||||
gtk_text_buffer_set_text (buffer, self->sample_text, -1);
|
||||
gtk_stack_set_visible_child_name (self->stack, "edit");
|
||||
gtk_widget_grab_focus (GTK_WIDGET (self->edit));
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkTextIter start, end;
|
||||
|
||||
g_free (self->sample_text);
|
||||
gtk_text_buffer_get_bounds (buffer, &start, &end);
|
||||
self->sample_text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
|
||||
|
||||
update_view (self);
|
||||
|
||||
gtk_stack_set_visible_child_name (self->stack, "content");
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SAMPLE_TEXT]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
waterfall_changed (GtkToggleButton *button,
|
||||
GParamSpec *pspec,
|
||||
FontView *self)
|
||||
{
|
||||
self->do_waterfall = gtk_toggle_button_get_active (button);
|
||||
update_view (self);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_IGNORE_SIZE]);
|
||||
}
|
||||
|
||||
static void
|
||||
font_view_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
FontView *self = FONT_VIEW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FONT_DESC:
|
||||
pango2_font_description_free (self->font_desc);
|
||||
self->font_desc = pango2_font_description_copy (g_value_get_boxed (value));
|
||||
break;
|
||||
|
||||
case PROP_SIZE:
|
||||
self->size = g_value_get_float (value);
|
||||
break;
|
||||
|
||||
case PROP_LETTERSPACING:
|
||||
self->letterspacing = g_value_get_int (value);
|
||||
break;
|
||||
|
||||
case PROP_LINE_HEIGHT:
|
||||
self->line_height = g_value_get_float (value);
|
||||
break;
|
||||
|
||||
case PROP_FOREGROUND:
|
||||
self->foreground = *(GdkRGBA *)g_value_get_boxed (value);
|
||||
break;
|
||||
|
||||
case PROP_BACKGROUND:
|
||||
self->background = *(GdkRGBA *)g_value_get_boxed (value);
|
||||
break;
|
||||
|
||||
case PROP_VARIATIONS:
|
||||
g_free (self->variations);
|
||||
self->variations = g_strdup (g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_FEATURES:
|
||||
g_free (self->features);
|
||||
self->features = g_strdup (g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_PALETTE:
|
||||
g_free (self->palette);
|
||||
self->palette = g_strdup (g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_SAMPLE_TEXT:
|
||||
g_free (self->sample_text);
|
||||
self->sample_text = g_strdup (g_value_get_string (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
|
||||
update_view (self);
|
||||
}
|
||||
|
||||
static void
|
||||
font_view_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
FontView *self = FONT_VIEW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FONT_DESC:
|
||||
g_value_set_boxed (value, self->font_desc);
|
||||
break;
|
||||
|
||||
case PROP_SIZE:
|
||||
g_value_set_float (value, self->size);
|
||||
break;
|
||||
|
||||
case PROP_LETTERSPACING:
|
||||
g_value_set_int (value, self->letterspacing);
|
||||
break;
|
||||
|
||||
case PROP_LINE_HEIGHT:
|
||||
g_value_set_float (value, self->line_height);
|
||||
break;
|
||||
|
||||
case PROP_FOREGROUND:
|
||||
g_value_set_boxed (value, &self->foreground);
|
||||
break;
|
||||
|
||||
case PROP_BACKGROUND:
|
||||
g_value_set_boxed (value, &self->background);
|
||||
break;
|
||||
|
||||
case PROP_VARIATIONS:
|
||||
g_value_set_string (value, self->variations);
|
||||
break;
|
||||
|
||||
case PROP_FEATURES:
|
||||
g_value_set_string (value, self->features);
|
||||
break;
|
||||
|
||||
case PROP_PALETTE:
|
||||
g_value_set_string (value, self->palette);
|
||||
break;
|
||||
|
||||
case PROP_SAMPLE_TEXT:
|
||||
g_value_set_string (value, self->sample_text);
|
||||
break;
|
||||
|
||||
case PROP_IGNORE_SIZE:
|
||||
g_value_set_boolean (value, self->do_waterfall);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
font_view_class_init (FontViewClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->dispose = font_view_dispose;
|
||||
object_class->finalize = font_view_finalize;
|
||||
object_class->get_property = font_view_get_property;
|
||||
object_class->set_property = font_view_set_property;
|
||||
|
||||
properties[PROP_FONT_DESC] =
|
||||
g_param_spec_boxed ("font-desc", "", "",
|
||||
PANGO2_TYPE_FONT_DESCRIPTION,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_SIZE] =
|
||||
g_param_spec_float ("size", "", "",
|
||||
0., 100., 12.,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_LETTERSPACING] =
|
||||
g_param_spec_int ("letterspacing", "", "",
|
||||
-G_MAXINT, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_LINE_HEIGHT] =
|
||||
g_param_spec_float ("line-height", "", "",
|
||||
0., 100., 1.,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_FOREGROUND] =
|
||||
g_param_spec_boxed ("foreground", "", "",
|
||||
GDK_TYPE_RGBA,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_BACKGROUND] =
|
||||
g_param_spec_boxed ("background", "", "",
|
||||
GDK_TYPE_RGBA,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_VARIATIONS] =
|
||||
g_param_spec_string ("variations", "", "",
|
||||
"",
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_FEATURES] =
|
||||
g_param_spec_string ("features", "", "",
|
||||
"",
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_PALETTE] =
|
||||
g_param_spec_string ("palette", "", "",
|
||||
PANGO2_COLOR_PALETTE_DEFAULT,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_SAMPLE_TEXT] =
|
||||
g_param_spec_string ("sample-text", "", "",
|
||||
"",
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_IGNORE_SIZE] =
|
||||
g_param_spec_boolean ("ignore-size", "", "",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
|
||||
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/fontexplorer/fontview.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontView, swin);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontView, content);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontView, stack);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontView, edit);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), toggle_edit);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), waterfall_changed);
|
||||
|
||||
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "fontview");
|
||||
}
|
||||
|
||||
FontView *
|
||||
font_view_new (void)
|
||||
{
|
||||
return g_object_new (FONT_VIEW_TYPE, NULL);
|
||||
}
|
||||
15
demos/font-explorer/fontview.h
Normal file
15
demos/font-explorer/fontview.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define FONT_VIEW_TYPE (font_view_get_type ())
|
||||
#define FONT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_VIEW_TYPE, FontView))
|
||||
|
||||
|
||||
typedef struct _FontView FontView;
|
||||
typedef struct _FontViewClass FontViewClass;
|
||||
|
||||
|
||||
GType font_view_get_type (void);
|
||||
FontView * font_view_new (void);
|
||||
91
demos/font-explorer/fontview.ui
Normal file
91
demos/font-explorer/fontview.ui
Normal file
@@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="FontView" parent="GtkWidget">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<style>
|
||||
<class name="view"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkStack" id="stack">
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">content</property>
|
||||
<property name="child">
|
||||
<object class="GtkScrolledWindow" id="swin">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="vscrollbar-policy">automatic</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="content">
|
||||
<property name="label">Content
Content</property>
|
||||
<property name="wrap">1</property>
|
||||
<property name="wrap-mode">word-char</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<property name="halign">fill</property>
|
||||
<property name="valign">fill</property>
|
||||
<style>
|
||||
<class name="view_background"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">edit</property>
|
||||
<property name="child">
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="vscrollbar-policy">automatic</property>
|
||||
<child>
|
||||
<object class="GtkTextView" id="edit">
|
||||
<property name="wrap-mode">word-char</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<style>
|
||||
<class name="linked"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="plain_toggle">
|
||||
<property name="label" translatable="yes">Plain</property>
|
||||
<property name="active">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="waterfall_toggle">
|
||||
<property name="label" translatable="yes">Waterfall</property>
|
||||
<property name="group">plain_toggle</property>
|
||||
<signal name="notify::active" handler="waterfall_changed"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton">
|
||||
<property name="icon-name">document-edit-symbolic</property>
|
||||
<property name="tooltip-text" translatable="yes">Edit the sample</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">end</property>
|
||||
<property name="hexpand">1</property>
|
||||
<signal name="clicked" handler="toggle_edit"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
336
demos/font-explorer/language-names.c
Normal file
336
demos/font-explorer/language-names.c
Normal file
@@ -0,0 +1,336 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <hb-ot.h>
|
||||
|
||||
#include "language-names.h"
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#else
|
||||
#ifndef ISO_CODES_PREFIX
|
||||
#define ISO_CODES_PREFIX "/usr"
|
||||
#endif
|
||||
|
||||
#define ISO_CODES_DATADIR ISO_CODES_PREFIX "/share/xml/iso-codes"
|
||||
#define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX "/share/locale"
|
||||
#endif
|
||||
|
||||
static GHashTable *language_map;
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
/* if we are using native Windows use native Windows API for language names */
|
||||
static BOOL CALLBACK
|
||||
get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param)
|
||||
{
|
||||
wchar_t *langname_w = NULL;
|
||||
wchar_t locale_abbrev_w[9];
|
||||
gchar *langname, *locale_abbrev, *locale, *p;
|
||||
gint i;
|
||||
const LCTYPE iso639_lctypes[] = { LOCALE_SISO639LANGNAME, LOCALE_SISO639LANGNAME2 };
|
||||
GHashTable *ht_scripts_langs = (GHashTable *) param;
|
||||
Pango2Language *lang;
|
||||
|
||||
gint langname_size, locale_abbrev_size;
|
||||
langname_size = GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, 0);
|
||||
if (langname_size == 0)
|
||||
return FALSE;
|
||||
|
||||
langname_w = g_new0 (wchar_t, langname_size);
|
||||
|
||||
if (langname_size == 0)
|
||||
return FALSE;
|
||||
|
||||
GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, langname_size);
|
||||
langname = g_utf16_to_utf8 (langname_w, -1, NULL, NULL, NULL);
|
||||
locale = g_utf16_to_utf8 (locale_w, -1, NULL, NULL, NULL);
|
||||
p = strchr (locale, '-');
|
||||
lang = pango2_language_from_string (locale);
|
||||
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
|
||||
g_hash_table_insert (ht_scripts_langs, lang, langname);
|
||||
|
||||
/*
|
||||
* Track 3+-letter ISO639-2/3 language codes as well (these have a max length of 9 including terminating NUL)
|
||||
* ISO639-2: iso639_lctypes[0] = LOCALE_SISO639LANGNAME
|
||||
* ISO639-3: iso639_lctypes[1] = LOCALE_SISO639LANGNAME2
|
||||
*/
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
locale_abbrev_size = GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, 0);
|
||||
if (locale_abbrev_size > 0)
|
||||
{
|
||||
GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, locale_abbrev_size);
|
||||
|
||||
locale_abbrev = g_utf16_to_utf8 (locale_abbrev_w, -1, NULL, NULL, NULL);
|
||||
lang = pango2_language_from_string (locale_abbrev);
|
||||
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
|
||||
g_hash_table_insert (ht_scripts_langs, lang, langname);
|
||||
|
||||
g_free (locale_abbrev);
|
||||
}
|
||||
}
|
||||
|
||||
g_free (locale);
|
||||
g_free (langname_w);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#else /* non-Windows */
|
||||
|
||||
static char *
|
||||
get_first_item_in_semicolon_list (const char *list)
|
||||
{
|
||||
char **items;
|
||||
char *item;
|
||||
|
||||
items = g_strsplit (list, "; ", 2);
|
||||
|
||||
item = g_strdup (items[0]);
|
||||
g_strfreev (items);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
static char *
|
||||
capitalize_utf8_string (const char *str)
|
||||
{
|
||||
char first[8] = { 0 };
|
||||
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
g_unichar_to_utf8 (g_unichar_totitle (g_utf8_get_char (str)), first);
|
||||
|
||||
return g_strconcat (first, g_utf8_offset_to_pointer (str, 1), NULL);
|
||||
}
|
||||
|
||||
static char *
|
||||
get_display_name (const char *language)
|
||||
{
|
||||
const char *translated;
|
||||
char *tmp;
|
||||
char *name;
|
||||
|
||||
translated = dgettext ("iso_639", language);
|
||||
|
||||
tmp = get_first_item_in_semicolon_list (translated);
|
||||
name = capitalize_utf8_string (tmp);
|
||||
g_free (tmp);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
static void
|
||||
languages_parse_start_tag (GMarkupParseContext *ctx,
|
||||
const char *element_name,
|
||||
const char **attr_names,
|
||||
const char **attr_values,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
const char *ccode_longB;
|
||||
const char *ccode_longT;
|
||||
const char *ccode;
|
||||
const char *ccode_id;
|
||||
const char *lang_name;
|
||||
char *display_name;
|
||||
const char *long_names[] = {
|
||||
"Dogri",
|
||||
"Greek, Modern",
|
||||
"Interlingua",
|
||||
"Konkani",
|
||||
"Tonga",
|
||||
"Turkish, Ottoman",
|
||||
};
|
||||
int i;
|
||||
|
||||
if (!(g_str_equal (element_name, "iso_639_entry") ||
|
||||
g_str_equal (element_name, "iso_639_3_entry")) ||
|
||||
attr_names == NULL ||
|
||||
attr_values == NULL)
|
||||
return;
|
||||
|
||||
ccode = NULL;
|
||||
ccode_longB = NULL;
|
||||
ccode_longT = NULL;
|
||||
ccode_id = NULL;
|
||||
lang_name = NULL;
|
||||
|
||||
while (*attr_names && *attr_values)
|
||||
{
|
||||
if (g_str_equal (*attr_names, "iso_639_1_code"))
|
||||
{
|
||||
if (**attr_values)
|
||||
{
|
||||
if (strlen (*attr_values) != 2)
|
||||
return;
|
||||
ccode = *attr_values;
|
||||
}
|
||||
}
|
||||
else if (g_str_equal (*attr_names, "iso_639_2B_code"))
|
||||
{
|
||||
if (**attr_values)
|
||||
{
|
||||
if (strlen (*attr_values) != 3)
|
||||
return;
|
||||
ccode_longB = *attr_values;
|
||||
}
|
||||
}
|
||||
else if (g_str_equal (*attr_names, "iso_639_2T_code"))
|
||||
{
|
||||
if (**attr_values)
|
||||
{
|
||||
if (strlen (*attr_values) != 3)
|
||||
return;
|
||||
ccode_longT = *attr_values;
|
||||
}
|
||||
}
|
||||
else if (g_str_equal (*attr_names, "id"))
|
||||
{
|
||||
if (**attr_values)
|
||||
{
|
||||
if (strlen (*attr_values) != 2 &&
|
||||
strlen (*attr_values) != 3)
|
||||
return;
|
||||
ccode_id = *attr_values;
|
||||
}
|
||||
}
|
||||
else if (g_str_equal (*attr_names, "name"))
|
||||
{
|
||||
lang_name = *attr_values;
|
||||
}
|
||||
|
||||
++attr_names;
|
||||
++attr_values;
|
||||
}
|
||||
|
||||
if (lang_name == NULL)
|
||||
return;
|
||||
|
||||
display_name = get_display_name (lang_name);
|
||||
|
||||
/* Fix up some egregious names */
|
||||
for (i = 0; i < G_N_ELEMENTS (long_names); i++)
|
||||
{
|
||||
if (g_str_has_prefix (display_name, long_names[i]))
|
||||
display_name[strlen (long_names[i])] = '\0';
|
||||
}
|
||||
|
||||
|
||||
if (ccode != NULL)
|
||||
g_hash_table_insert (language_map,
|
||||
pango2_language_from_string (ccode),
|
||||
g_strdup (display_name));
|
||||
|
||||
if (ccode_longB != NULL)
|
||||
g_hash_table_insert (language_map,
|
||||
pango2_language_from_string (ccode_longB),
|
||||
g_strdup (display_name));
|
||||
|
||||
if (ccode_longT != NULL)
|
||||
g_hash_table_insert (language_map,
|
||||
pango2_language_from_string (ccode_longT),
|
||||
g_strdup (display_name));
|
||||
|
||||
if (ccode_id != NULL)
|
||||
g_hash_table_insert (language_map,
|
||||
pango2_language_from_string (ccode_id),
|
||||
g_strdup (display_name));
|
||||
|
||||
g_free (display_name);
|
||||
}
|
||||
|
||||
static void
|
||||
languages_variant_init (const char *variant)
|
||||
{
|
||||
gboolean res;
|
||||
gsize buf_len;
|
||||
char *buf;
|
||||
char *filename;
|
||||
GError *error;
|
||||
|
||||
bindtextdomain (variant, ISO_CODES_LOCALESDIR);
|
||||
bind_textdomain_codeset (variant, "UTF-8");
|
||||
|
||||
error = NULL;
|
||||
filename = g_strconcat (ISO_CODES_DATADIR, "/", variant, ".xml", NULL);
|
||||
res = g_file_get_contents (filename, &buf, &buf_len, &error);
|
||||
if (res)
|
||||
{
|
||||
GMarkupParseContext *ctx = NULL;
|
||||
GMarkupParser parser = { languages_parse_start_tag, NULL, NULL, NULL, NULL };
|
||||
|
||||
ctx = g_markup_parse_context_new (&parser, 0, NULL, NULL);
|
||||
|
||||
res = g_markup_parse_context_parse (ctx, buf, buf_len, &error);
|
||||
g_free (ctx);
|
||||
|
||||
if (!res)
|
||||
{
|
||||
g_warning ("Failed to parse '%s': %s\n", filename, error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Failed to load '%s': %s\n", filename, error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_free (filename);
|
||||
g_free (buf);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
languages_init (void)
|
||||
{
|
||||
if (language_map)
|
||||
return;
|
||||
|
||||
language_map = g_hash_table_new_full (NULL, NULL, NULL, g_free);
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
g_return_if_fail (EnumSystemLocalesEx (&get_win32_all_locales_scripts, LOCALE_ALL, (LPARAM) language_map, NULL));
|
||||
#else
|
||||
languages_variant_init ("iso_639");
|
||||
languages_variant_init ("iso_639_3");
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *
|
||||
get_language_name (Pango2Language *language)
|
||||
{
|
||||
languages_init ();
|
||||
|
||||
return (const char *) g_hash_table_lookup (language_map, language);
|
||||
}
|
||||
|
||||
const char *
|
||||
get_language_name_for_tag (guint32 tag)
|
||||
{
|
||||
hb_language_t lang;
|
||||
const char *s;
|
||||
|
||||
lang = hb_ot_tag_to_language (tag);
|
||||
s = hb_language_to_string (lang);
|
||||
|
||||
return get_language_name (pango2_language_from_string (s));
|
||||
}
|
||||
13
demos/font-explorer/language-names.h
Normal file
13
demos/font-explorer/language-names.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef LANGUAGE_NAMES_H
|
||||
#define LANGUAGE_NAMES_H
|
||||
|
||||
#include <pango2/pango.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
const char * get_language_name (Pango2Language *language);
|
||||
const char * get_language_name_for_tag (guint32 tag);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
8
demos/font-explorer/main.c
Normal file
8
demos/font-explorer/main.c
Normal file
@@ -0,0 +1,8 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <fontexplorerapp.h>
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
return g_application_run (G_APPLICATION (font_explorer_app_new ()), argc, argv);
|
||||
}
|
||||
27
demos/font-explorer/meson.build
Normal file
27
demos/font-explorer/meson.build
Normal file
@@ -0,0 +1,27 @@
|
||||
fontexplorer_sources = [
|
||||
'main.c',
|
||||
'fontexplorerapp.c',
|
||||
'fontexplorerwin.c',
|
||||
'fontcontrols.c',
|
||||
'samplechooser.c',
|
||||
'fontcolors.c',
|
||||
'fontfeatures.c',
|
||||
'fontvariations.c',
|
||||
'fontview.c',
|
||||
'rangeedit.c',
|
||||
'language-names.c',
|
||||
]
|
||||
|
||||
fontexplorer_resources = gnome.compile_resources('fontexplorer_resources',
|
||||
'fontexplorer.gresource.xml',
|
||||
source_dir: '.',
|
||||
)
|
||||
|
||||
executable('gtk4-font-explorer',
|
||||
sources: [fontexplorer_sources, fontexplorer_resources],
|
||||
c_args: common_cflags,
|
||||
dependencies: [ libgtk_dep, demo_conf_h ],
|
||||
include_directories: confinc,
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true,
|
||||
)
|
||||
173
demos/font-explorer/rangeedit.c
Normal file
173
demos/font-explorer/rangeedit.c
Normal file
@@ -0,0 +1,173 @@
|
||||
#include "rangeedit.h"
|
||||
#include <gtk/gtk.h>
|
||||
#include <hb-ot.h>
|
||||
|
||||
enum {
|
||||
PROP_ADJUSTMENT = 1,
|
||||
PROP_DEFAULT_VALUE,
|
||||
PROP_N_CHARS,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
struct _RangeEdit
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
GtkAdjustment *adjustment;
|
||||
GtkScale *scale;
|
||||
GtkEntry *entry;
|
||||
double default_value;
|
||||
int n_chars;
|
||||
};
|
||||
|
||||
struct _RangeEditClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (RangeEdit, range_edit, GTK_TYPE_WIDGET);
|
||||
|
||||
static void
|
||||
range_edit_init (RangeEdit *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
range_edit_dispose (GObject *object)
|
||||
{
|
||||
gtk_widget_clear_template (GTK_WIDGET (object), RANGE_EDIT_TYPE);
|
||||
|
||||
G_OBJECT_CLASS (range_edit_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
range_edit_get_property (GObject *object,
|
||||
unsigned int prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
RangeEdit *self = RANGE_EDIT (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ADJUSTMENT:
|
||||
g_value_set_object (value, self->adjustment);
|
||||
break;
|
||||
|
||||
case PROP_DEFAULT_VALUE:
|
||||
g_value_set_double (value, self->default_value);
|
||||
break;
|
||||
|
||||
case PROP_N_CHARS:
|
||||
g_value_set_int (value, self->n_chars);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
adjustment_changed (GtkAdjustment *adjustment,
|
||||
RangeEdit *self)
|
||||
{
|
||||
char *str;
|
||||
|
||||
str = g_strdup_printf ("%.1f", gtk_adjustment_get_value (adjustment));
|
||||
gtk_editable_set_text (GTK_EDITABLE (self->entry), str);
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
static void
|
||||
range_edit_set_property (GObject *object,
|
||||
unsigned int prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
RangeEdit *self = RANGE_EDIT (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ADJUSTMENT:
|
||||
g_set_object (&self->adjustment, g_value_get_object (value));
|
||||
g_signal_connect (self->adjustment, "value-changed", G_CALLBACK (adjustment_changed), self);
|
||||
adjustment_changed (self->adjustment, self);
|
||||
break;
|
||||
|
||||
case PROP_DEFAULT_VALUE:
|
||||
self->default_value = g_value_get_double (value);
|
||||
break;
|
||||
|
||||
case PROP_N_CHARS:
|
||||
self->n_chars = g_value_get_int (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
range_edit_constructed (GObject *object)
|
||||
{
|
||||
RangeEdit *self = RANGE_EDIT (object);
|
||||
|
||||
gtk_scale_add_mark (self->scale, self->default_value, GTK_POS_TOP, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
entry_activated (GtkEntry *entry,
|
||||
RangeEdit *self)
|
||||
{
|
||||
double value;
|
||||
char *err = NULL;
|
||||
|
||||
value = g_strtod (gtk_editable_get_text (GTK_EDITABLE (entry)), &err);
|
||||
if (err != NULL)
|
||||
gtk_adjustment_set_value (self->adjustment, value);
|
||||
}
|
||||
|
||||
static void
|
||||
range_edit_class_init (RangeEditClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->dispose = range_edit_dispose;
|
||||
object_class->get_property = range_edit_get_property;
|
||||
object_class->set_property = range_edit_set_property;
|
||||
object_class->constructed = range_edit_constructed;
|
||||
|
||||
properties[PROP_ADJUSTMENT] =
|
||||
g_param_spec_object ("adjustment", "", "",
|
||||
GTK_TYPE_ADJUSTMENT,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
properties[PROP_DEFAULT_VALUE] =
|
||||
g_param_spec_double ("default-value", "", "",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0.,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
properties[PROP_N_CHARS] =
|
||||
g_param_spec_int ("n-chars", "", "",
|
||||
0, G_MAXINT, 10,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/fontexplorer/rangeedit.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), RangeEdit, scale);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), RangeEdit, entry);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), entry_activated);
|
||||
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "rangeedit");
|
||||
}
|
||||
|
||||
RangeEdit *
|
||||
range_edit_new (void)
|
||||
{
|
||||
return g_object_new (RANGE_EDIT_TYPE, NULL);
|
||||
}
|
||||
15
demos/font-explorer/rangeedit.h
Normal file
15
demos/font-explorer/rangeedit.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define RANGE_EDIT_TYPE (range_edit_get_type ())
|
||||
#define RANGE_EDIT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RANGE_EDIT_TYPE, RangeEdit))
|
||||
|
||||
|
||||
typedef struct _RangeEdit RangeEdit;
|
||||
typedef struct _RangeEditClass RangeEditClass;
|
||||
|
||||
|
||||
GType range_edit_get_type (void);
|
||||
RangeEdit * range_edit_new (void);
|
||||
24
demos/font-explorer/rangeedit.ui
Normal file
24
demos/font-explorer/rangeedit.ui
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="RangeEdit" parent="GtkWidget">
|
||||
<property name="layout-manager">
|
||||
<object class="GtkBoxLayout">
|
||||
<property name="spacing">10</property>
|
||||
</object>
|
||||
</property>
|
||||
<child>
|
||||
<object class="GtkScale" id="scale">
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="adjustment" bind-source="RangeEdit" bind-flags="sync-create"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry">
|
||||
<property name="width-chars" bind-source="RangeEdit" bind-property="n-chars" bind-flags="sync-create"/>
|
||||
<property name="max-width-chars" bind-source="RangeEdit" bind-property="n-chars" bind-flags="sync-create"/>
|
||||
<signal name="activate" handler="entry_activated"/>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
162
demos/font-explorer/samplechooser.c
Normal file
162
demos/font-explorer/samplechooser.c
Normal file
@@ -0,0 +1,162 @@
|
||||
#include "samplechooser.h"
|
||||
#include <gtk/gtk.h>
|
||||
#include <hb-ot.h>
|
||||
|
||||
enum {
|
||||
PROP_SAMPLE_TEXT = 1,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
struct _SampleChooser
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
int sample;
|
||||
const char *sample_text;
|
||||
};
|
||||
|
||||
struct _SampleChooserClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(SampleChooser, sample_chooser, GTK_TYPE_WIDGET);
|
||||
|
||||
static const char *pangrams[] = {
|
||||
"The quick brown fox jumps over the lazy dog.",
|
||||
"Waltz, bad nymph, for quick jigs vex.",
|
||||
"Quick zephyrs blow, vexing daft Jim.",
|
||||
"Crazy Fredrick bought many very exquisite opal jewels.",
|
||||
"Jaded zombies acted quaintly but kept driving their oxen forward.",
|
||||
};
|
||||
|
||||
static const char *paragraphs[] = {
|
||||
"Grumpy wizards make toxic brew for the evil Queen and Jack. A quick movement of the enemy will jeopardize six gunboats. The job of waxing linoleum frequently peeves chintzy kids. My girl wove six dozen plaid jackets before she quit. Twelve ziggurats quickly jumped a finch box.",
|
||||
" Разъяренный чтец эгоистично бьёт пятью жердями шустрого фехтовальщика. Наш банк вчера же выплатил Ф.Я. Эйхгольду комиссию за ценные вещи. Эх, чужак, общий съём цен шляп (юфть) – вдрызг! В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!",
|
||||
"Τάχιστη αλώπηξ βαφής ψημένη γη, δρασκελίζει υπέρ νωθρού κυνός",
|
||||
};
|
||||
|
||||
static const char *alphabets[] = {
|
||||
"abcdefghijklmnopqrstuvwxyz",
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
||||
"0123456789",
|
||||
"!@#$%^&*()?",
|
||||
};
|
||||
|
||||
static const char *titles[] = {
|
||||
"From My Cold Dead Hands",
|
||||
"From Afar Upon the Back of a Tiger",
|
||||
"Spontaneous Apple Creation",
|
||||
"Big Bizness (Screwed & Chopped)",
|
||||
"Pizza Shop Extended",
|
||||
"Good News & Bad News",
|
||||
};
|
||||
|
||||
static void
|
||||
next_pangram (GtkButton *button,
|
||||
SampleChooser *self)
|
||||
{
|
||||
self->sample++;
|
||||
self->sample_text = pangrams[self->sample % G_N_ELEMENTS (pangrams)];
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SAMPLE_TEXT]);
|
||||
}
|
||||
|
||||
static void
|
||||
next_paragraph (GtkButton *button,
|
||||
SampleChooser *self)
|
||||
{
|
||||
self->sample++;
|
||||
self->sample_text = paragraphs[self->sample % G_N_ELEMENTS (paragraphs)];
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SAMPLE_TEXT]);
|
||||
}
|
||||
|
||||
static void
|
||||
next_alphabet (GtkButton *button,
|
||||
SampleChooser *self)
|
||||
{
|
||||
self->sample++;
|
||||
self->sample_text = alphabets[self->sample % G_N_ELEMENTS (alphabets)];
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SAMPLE_TEXT]);
|
||||
}
|
||||
|
||||
static void
|
||||
next_title (GtkButton *button,
|
||||
SampleChooser *self)
|
||||
{
|
||||
self->sample++;
|
||||
self->sample_text = titles[self->sample % G_N_ELEMENTS (titles)];
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SAMPLE_TEXT]);
|
||||
}
|
||||
|
||||
static void
|
||||
sample_chooser_init (SampleChooser *self)
|
||||
{
|
||||
self->sample_text = "Boring sample text";
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
sample_chooser_dispose (GObject *object)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
gtk_widget_clear_template (GTK_WIDGET (object), SAMPLE_CHOOSER_TYPE);
|
||||
|
||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (object))) != NULL)
|
||||
gtk_widget_unparent (child);
|
||||
|
||||
G_OBJECT_CLASS (sample_chooser_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
sample_chooser_get_property (GObject *object,
|
||||
unsigned int prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
SampleChooser *self = SAMPLE_CHOOSER (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SAMPLE_TEXT:
|
||||
g_value_set_string (value, self->sample_text);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sample_chooser_class_init (SampleChooserClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->dispose = sample_chooser_dispose;
|
||||
object_class->get_property = sample_chooser_get_property;
|
||||
|
||||
properties[PROP_SAMPLE_TEXT] =
|
||||
g_param_spec_string ("sample-text", "", "",
|
||||
"",
|
||||
G_PARAM_READABLE);
|
||||
|
||||
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/fontexplorer/samplechooser.ui");
|
||||
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), next_pangram);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), next_paragraph);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), next_alphabet);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), next_title);
|
||||
|
||||
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "samplechooser");
|
||||
}
|
||||
|
||||
SampleChooser *
|
||||
sample_chooser_new (void)
|
||||
{
|
||||
return g_object_new (SAMPLE_CHOOSER_TYPE, NULL);
|
||||
}
|
||||
15
demos/font-explorer/samplechooser.h
Normal file
15
demos/font-explorer/samplechooser.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define SAMPLE_CHOOSER_TYPE (sample_chooser_get_type ())
|
||||
#define SAMPLE_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SAMPLE_CHOOSER_TYPE, SampleChooser))
|
||||
|
||||
|
||||
typedef struct _SampleChooser SampleChooser;
|
||||
typedef struct _SampleChooserClass SampleChooserClass;
|
||||
|
||||
|
||||
GType sample_chooser_get_type (void);
|
||||
SampleChooser * sample_chooser_new (void);
|
||||
46
demos/font-explorer/samplechooser.ui
Normal file
46
demos/font-explorer/samplechooser.ui
Normal file
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="SampleChooser" parent="GtkWidget">
|
||||
<property name="layout-manager"><object class="GtkGridLayout"/></property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">Pangram</property>
|
||||
<signal name="clicked" handler="next_pangram"/>
|
||||
<layout>
|
||||
<property name="row">0</property>
|
||||
<property name="column">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">Paragraph</property>
|
||||
<signal name="clicked" handler="next_paragraph"/>
|
||||
<layout>
|
||||
<property name="row">0</property>
|
||||
<property name="column">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">Alphabet</property>
|
||||
<signal name="clicked" handler="next_alphabet"/>
|
||||
<layout>
|
||||
<property name="row">1</property>
|
||||
<property name="column">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">Title</property>
|
||||
<signal name="clicked" handler="next_title"/>
|
||||
<layout>
|
||||
<property name="row">1</property>
|
||||
<property name="column">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -341,16 +341,13 @@ do_clipboard (GtkWidget *do_widget)
|
||||
GtkWidget *button;
|
||||
|
||||
scope = gtk_builder_cscope_new ();
|
||||
gtk_builder_cscope_add_callback_symbols (GTK_BUILDER_CSCOPE (scope),
|
||||
"copy_button_clicked", G_CALLBACK (copy_button_clicked),
|
||||
"paste_button_clicked", G_CALLBACK (paste_button_clicked),
|
||||
"source_changed_cb", G_CALLBACK (source_changed_cb),
|
||||
"text_changed_cb", G_CALLBACK (text_changed_cb),
|
||||
"open_file_cb", G_CALLBACK (open_file_cb),
|
||||
"on_drop", G_CALLBACK (on_drop),
|
||||
"drag_prepare", G_CALLBACK (drag_prepare),
|
||||
NULL);
|
||||
|
||||
gtk_builder_cscope_add_callback (scope, copy_button_clicked);
|
||||
gtk_builder_cscope_add_callback (scope, paste_button_clicked);
|
||||
gtk_builder_cscope_add_callback (scope, source_changed_cb);
|
||||
gtk_builder_cscope_add_callback (scope, text_changed_cb);
|
||||
gtk_builder_cscope_add_callback (scope, open_file_cb);
|
||||
gtk_builder_cscope_add_callback (scope, on_drop);
|
||||
gtk_builder_cscope_add_callback (scope, drag_prepare);
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_set_scope (builder, scope);
|
||||
gtk_builder_add_from_resource (builder, "/clipboard/clipboard.ui", NULL);
|
||||
|
||||
@@ -260,12 +260,13 @@ mask_entry_set_background (MaskEntry *entry)
|
||||
{
|
||||
if (!g_regex_match_simple (entry->mask, gtk_editable_get_text (GTK_EDITABLE (entry)), 0, 0))
|
||||
{
|
||||
PangoAttrList *attrs;
|
||||
Pango2AttrList *attrs;
|
||||
Pango2Color color = { 65535, 32767, 32767, 65535 };
|
||||
|
||||
attrs = pango_attr_list_new ();
|
||||
pango_attr_list_insert (attrs, pango_attr_foreground_new (65535, 32767, 32767));
|
||||
attrs = pango2_attr_list_new ();
|
||||
pango2_attr_list_insert (attrs, pango2_attr_foreground_new (&color));
|
||||
gtk_entry_set_attributes (GTK_ENTRY (entry), attrs);
|
||||
pango_attr_list_unref (attrs);
|
||||
pango2_attr_list_unref (attrs);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,11 +84,11 @@ do_css_basics (GtkWidget *do_widget)
|
||||
text = gtk_text_buffer_new (NULL);
|
||||
gtk_text_buffer_create_tag (text,
|
||||
"warning",
|
||||
"underline", PANGO_UNDERLINE_SINGLE,
|
||||
"underline", PANGO2_LINE_STYLE_SOLID,
|
||||
NULL);
|
||||
gtk_text_buffer_create_tag (text,
|
||||
"error",
|
||||
"underline", PANGO_UNDERLINE_ERROR,
|
||||
"underline", PANGO2_LINE_STYLE_DOTTED,
|
||||
NULL);
|
||||
|
||||
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||
|
||||
@@ -122,11 +122,11 @@ do_css_multiplebgs (GtkWidget *do_widget)
|
||||
text = gtk_text_buffer_new (NULL);
|
||||
gtk_text_buffer_create_tag (text,
|
||||
"warning",
|
||||
"underline", PANGO_UNDERLINE_SINGLE,
|
||||
"underline", PANGO2_LINE_STYLE_SOLID,
|
||||
NULL);
|
||||
gtk_text_buffer_create_tag (text,
|
||||
"error",
|
||||
"underline", PANGO_UNDERLINE_ERROR,
|
||||
"underline", PANGO2_LINE_STYLE_DOTTED,
|
||||
NULL);
|
||||
|
||||
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||
|
||||
@@ -93,11 +93,11 @@ do_css_pixbufs (GtkWidget *do_widget)
|
||||
text = gtk_text_buffer_new (NULL);
|
||||
gtk_text_buffer_create_tag (text,
|
||||
"warning",
|
||||
"underline", PANGO_UNDERLINE_SINGLE,
|
||||
"underline", PANGO2_LINE_STYLE_SOLID,
|
||||
NULL);
|
||||
gtk_text_buffer_create_tag (text,
|
||||
"error",
|
||||
"underline", PANGO_UNDERLINE_ERROR,
|
||||
"underline", PANGO2_LINE_STYLE_DOTTED,
|
||||
NULL);
|
||||
|
||||
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||
|
||||
@@ -111,11 +111,11 @@ do_css_shadows (GtkWidget *do_widget)
|
||||
text = gtk_text_buffer_new (NULL);
|
||||
gtk_text_buffer_create_tag (text,
|
||||
"warning",
|
||||
"underline", PANGO_UNDERLINE_SINGLE,
|
||||
"underline", PANGO2_LINE_STYLE_SOLID,
|
||||
NULL);
|
||||
gtk_text_buffer_create_tag (text,
|
||||
"error",
|
||||
"underline", PANGO_UNDERLINE_ERROR,
|
||||
"underline", PANGO2_LINE_STYLE_DOTTED,
|
||||
NULL);
|
||||
|
||||
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||
|
||||
@@ -329,6 +329,7 @@
|
||||
<file>pickers.c</file>
|
||||
<file>printing.c</file>
|
||||
<file>revealer.c</file>
|
||||
<file>read_more.c</file>
|
||||
<file>rotated_text.c</file>
|
||||
<file>scale.c</file>
|
||||
<file>search_entry.c</file>
|
||||
@@ -375,7 +376,7 @@
|
||||
<file>glarea-gles.vs.glsl</file>
|
||||
</gresource>
|
||||
<gresource prefix="/font_features">
|
||||
<file>font-features.ui</file>
|
||||
<file>font_features.ui</file>
|
||||
<file>fontplane.c</file>
|
||||
</gresource>
|
||||
<gresource prefix="/spinbutton">
|
||||
|
||||
@@ -263,7 +263,7 @@ drop_down_new_from_strings (const char *const *titles,
|
||||
static char *
|
||||
get_family_name (gpointer item)
|
||||
{
|
||||
return g_strdup (pango_font_family_get_name (PANGO_FONT_FAMILY (item)));
|
||||
return g_strdup (pango2_font_family_get_name (PANGO2_FONT_FAMILY (item)));
|
||||
}
|
||||
|
||||
static char *
|
||||
@@ -326,8 +326,8 @@ bind_highlight_item (GtkSignalListItemFactory *factory,
|
||||
{
|
||||
MatchObject *obj;
|
||||
GtkWidget *label;
|
||||
PangoAttrList *attrs;
|
||||
PangoAttribute *attr;
|
||||
Pango2AttrList *attrs;
|
||||
Pango2Attribute *attr;
|
||||
const char *str;
|
||||
|
||||
obj = MATCH_OBJECT (gtk_list_item_get_item (item));
|
||||
@@ -336,13 +336,14 @@ bind_highlight_item (GtkSignalListItemFactory *factory,
|
||||
str = match_object_get_string (obj);
|
||||
|
||||
gtk_label_set_label (GTK_LABEL (label), str);
|
||||
attrs = pango_attr_list_new ();
|
||||
attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
|
||||
attr->start_index = match_object_get_match_start (obj);
|
||||
attr->end_index = match_object_get_match_end (obj);
|
||||
pango_attr_list_insert (attrs, attr);
|
||||
attrs = pango2_attr_list_new ();
|
||||
attr = pango2_attr_weight_new (PANGO2_WEIGHT_BOLD);
|
||||
pango2_attribute_set_range (attr,
|
||||
match_object_get_match_start (obj),
|
||||
match_object_get_match_end (obj));
|
||||
pango2_attr_list_insert (attrs, attr);
|
||||
gtk_label_set_attributes (GTK_LABEL (label), attrs);
|
||||
pango_attr_list_unref (attrs);
|
||||
pango2_attr_list_unref (attrs);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -434,7 +435,7 @@ do_dropdown (GtkWidget *do_widget)
|
||||
|
||||
button = gtk_drop_down_new (NULL, NULL);
|
||||
|
||||
model = G_LIST_MODEL (pango_cairo_font_map_get_default ());
|
||||
model = G_LIST_MODEL (pango2_font_map_get_default ());
|
||||
gtk_drop_down_set_model (GTK_DROP_DOWN (button), model);
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (button), 0);
|
||||
|
||||
|
||||
@@ -90,12 +90,9 @@ do_errorstates (GtkWidget *do_widget)
|
||||
toplevel = GTK_WIDGET (gtk_widget_get_root (do_widget));
|
||||
|
||||
scope = gtk_builder_cscope_new ();
|
||||
gtk_builder_cscope_add_callback_symbols (GTK_BUILDER_CSCOPE (scope),
|
||||
"validate_more_details", G_CALLBACK (validate_more_details),
|
||||
"mode_switch_state_set", G_CALLBACK (mode_switch_state_set),
|
||||
"level_scale_value_changed", G_CALLBACK (level_scale_value_changed),
|
||||
NULL);
|
||||
|
||||
gtk_builder_cscope_add_callback (scope, validate_more_details);
|
||||
gtk_builder_cscope_add_callback (scope, mode_switch_state_set);
|
||||
gtk_builder_cscope_add_callback (scope, level_scale_value_changed);
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_set_scope (builder, scope);
|
||||
gtk_builder_expose_object (builder, "toplevel", G_OBJECT (toplevel));
|
||||
|
||||
@@ -1,190 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkWindow" id="window">
|
||||
<property name="default-width">600</property>
|
||||
<property name="default-height">500</property>
|
||||
<property name="title">Font Explorer</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<child>
|
||||
<object class="GtkButton" id="reset">
|
||||
<property name="receives-default">1</property>
|
||||
<property name="tooltip-text">Reset</property>
|
||||
<property name="icon-name">view-refresh-symbolic</property>
|
||||
<signal name="clicked" handler="font_features_reset_features" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<child>
|
||||
<object class="GtkViewport">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
<property name="margin-top">10</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkFontButton" id="font">
|
||||
<property name="receives-default">1</property>
|
||||
<property name="font">Sans 12</property>
|
||||
<property name="level">family|style|size|variations|features</property>
|
||||
<signal name="font-set" handler="font_features_font_changed" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkExpander">
|
||||
<child type="label">
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Font Features</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"></attribute>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="feature_list">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="script_lang">
|
||||
<property name="margin-top">10</property>
|
||||
<signal name="changed" handler="font_features_script_changed" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkExpander">
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="variations_heading">
|
||||
<property name="label" translatable="yes">Font Variations</property>
|
||||
<property name="xalign">0</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"></attribute>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGrid" id="variations_grid">
|
||||
<property name="column-spacing">10</property>
|
||||
<property name="row-spacing">10</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="view"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<property name="margin-start">20</property>
|
||||
<property name="margin-end">20</property>
|
||||
<property name="margin-top">20</property>
|
||||
<property name="margin-bottom">20</property>
|
||||
<property name="spacing">20</property>
|
||||
<child>
|
||||
<object class="GtkStack" id="stack">
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">label</property>
|
||||
<property name="child">
|
||||
<object class="GtkLabel" id="label">
|
||||
<property name="wrap">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0</property>
|
||||
<property name="valign">start</property>
|
||||
<property name="selectable">1</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">entry</property>
|
||||
<property name="child">
|
||||
<object class="GtkEntry" id="entry">
|
||||
<property name="text">Grumpy wizards make toxic brew for the evil Queen and Jack. A quick movement of the enemy will jeopardize six gunboats. The job of waxing linoleum frequently peeves chintzy kids. My girl wove six dozen plaid jackets before she quit. Twelve ziggurats quickly jumped a finch box.
|
||||
|
||||
Разъяренный чтец эгоистично бьёт пятью жердями шустрого фехтовальщика. Наш банк вчера же выплатил Ф.Я. Эйхгольду комиссию за ценные вещи. Эх, чужак, общий съём цен шляп (юфть) – вдрызг! В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!
|
||||
|
||||
Τάχιστη αλώπηξ βαφής ψημένη γη, δρασκελίζει υπέρ νωθρού κυνός</property>
|
||||
<signal name="activate" handler="font_features_stop_edit"/>
|
||||
<property name="valign">start</property>
|
||||
<property name="width-chars">50</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="settings">
|
||||
<property name="wrap">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="valign">end</property>
|
||||
<property name="width-chars">50</property>
|
||||
<property name="max-width-chars">50</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<style>
|
||||
<class name="monospace"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="description">
|
||||
<property name="wrap">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="valign">end</property>
|
||||
<property name="width-chars">50</property>
|
||||
<property name="max-width-chars">50</property>
|
||||
<property name="hexpand">1</property>
|
||||
<style>
|
||||
<class name="monospace"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="edit_toggle">
|
||||
<property name="icon-name">document-edit-symbolic</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">end</property>
|
||||
<signal name="toggled" handler="font_features_toggle_edit"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
File diff suppressed because it is too large
Load Diff
65
demos/gtk-demo/font_features.c.rej
Normal file
65
demos/gtk-demo/font_features.c.rej
Normal file
@@ -0,0 +1,65 @@
|
||||
--- demos/gtk-demo/font_features.c
|
||||
+++ demos/gtk-demo/font_features.c
|
||||
@@ -434,7 +434,7 @@ static void
|
||||
update_display (void)
|
||||
{
|
||||
GString *s;
|
||||
- const char *text;
|
||||
+ char *text;
|
||||
gboolean has_feature;
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel *model;
|
||||
@@ -452,8 +452,12 @@ update_display (void)
|
||||
gboolean do_waterfall;
|
||||
GString *waterfall;
|
||||
char *palette;
|
||||
+ GtkTextBuffer *buffer;
|
||||
+ GtkTextIter start_iter, end_iter;
|
||||
|
||||
- text = gtk_editable_get_text (GTK_EDITABLE (demo->the_entry));
|
||||
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (demo->the_entry));
|
||||
+ gtk_text_buffer_get_bounds (buffer, &start_iter, &end_iter);
|
||||
+ text = gtk_text_buffer_get_text (buffer, &start_iter, &end_iter, FALSE);
|
||||
text_len = strlen (text);
|
||||
|
||||
do_waterfall = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (demo->waterfall_toggle));
|
||||
@@ -631,6 +635,8 @@ update_display (void)
|
||||
pango2_font_description_free (desc);
|
||||
g_free (features);
|
||||
pango2_attr_list_unref (attrs);
|
||||
+
|
||||
+ g_free (text);
|
||||
}
|
||||
|
||||
static Pango2Font *
|
||||
@@ -1603,8 +1609,12 @@ font_features_toggle_edit (void)
|
||||
{
|
||||
if (strcmp (gtk_stack_get_visible_child_name (GTK_STACK (demo->stack)), "entry") != 0)
|
||||
{
|
||||
+ GtkTextBuffer *buffer;
|
||||
+ GtkTextIter start, end;
|
||||
g_free (demo->text);
|
||||
- demo->text = g_strdup (gtk_editable_get_text (GTK_EDITABLE (demo->the_entry)));
|
||||
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (demo->the_entry));
|
||||
+ gtk_text_buffer_get_bounds (buffer, &start, &end);
|
||||
+ demo->text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (demo->stack), "entry");
|
||||
gtk_widget_grab_focus (demo->the_entry);
|
||||
gtk_adjustment_set_value (gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (demo->swin)), 0);
|
||||
@@ -1632,7 +1642,7 @@ entry_key_press (GtkEventController *controller,
|
||||
{
|
||||
if (keyval == GDK_KEY_Escape)
|
||||
{
|
||||
- gtk_editable_set_text (GTK_EDITABLE (entry), demo->text);
|
||||
+ gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (demo->the_entry)), demo->text, -1);
|
||||
return GDK_EVENT_STOP;
|
||||
}
|
||||
|
||||
@@ -1701,7 +1711,6 @@ do_font_features (GtkWidget *do_widget)
|
||||
basic_value_changed (demo->line_height_adjustment, demo->line_height_entry);
|
||||
|
||||
controller = gtk_event_controller_key_new ();
|
||||
- g_object_set_data_full (G_OBJECT (demo->the_entry), "controller", g_object_ref (controller), g_object_unref);
|
||||
g_signal_connect (controller, "key-pressed", G_CALLBACK (entry_key_press), demo->the_entry);
|
||||
gtk_widget_add_controller (demo->the_entry, controller);
|
||||
|
||||
476
demos/gtk-demo/font_features.ui
Normal file
476
demos/gtk-demo/font_features.ui
Normal file
@@ -0,0 +1,476 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkAdjustment" id="size_adjustment">
|
||||
<property name="lower">7</property>
|
||||
<property name="upper">100</property>
|
||||
<property name="value">14</property>
|
||||
<property name="step_increment">0.5</property>
|
||||
<property name="page_increment">10</property>
|
||||
<signal name="value-changed" handler="basic_value_changed" object="size_entry" swapped="false"/>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="letterspacing_adjustment">
|
||||
<property name="lower">-1024</property>
|
||||
<property name="upper">8192</property>
|
||||
<property name="value">0</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">512</property>
|
||||
<signal name="value-changed" handler="basic_value_changed" object="letterspacing_entry" swapped="false"/>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="line_height_adjustment">
|
||||
<property name="lower">0.75</property>
|
||||
<property name="upper">2.5</property>
|
||||
<property name="value">1.0</property>
|
||||
<property name="step_increment">0.1</property>
|
||||
<property name="page_increment">1</property>
|
||||
<signal name="value-changed" handler="basic_value_changed" object="line_height_entry" swapped="false"/>
|
||||
</object>
|
||||
<object class="GtkWindow" id="window">
|
||||
<property name="default-width">600</property>
|
||||
<property name="default-height">500</property>
|
||||
<property name="title">Font Explorer</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<child>
|
||||
<object class="GtkButton" id="reset">
|
||||
<property name="receives-default">1</property>
|
||||
<property name="tooltip-text">Reset</property>
|
||||
<property name="icon-name">view-refresh-symbolic</property>
|
||||
<signal name="clicked" handler="font_features_reset_basic" swapped="no"/>
|
||||
<signal name="clicked" handler="font_features_reset_features" swapped="no"/>
|
||||
<signal name="clicked" handler="font_features_reset_variations" swapped="no"/>
|
||||
<signal name="clicked" handler="font_features_reset_colors" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<child>
|
||||
<object class="GtkViewport">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
<property name="margin-top">10</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkFontButton" id="font">
|
||||
<property name="receives-default">1</property>
|
||||
<property name="font">Sans 12</property>
|
||||
<property name="level">family|style</property>
|
||||
<signal name="font-set" handler="font_features_font_changed" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="column-spacing">10</property>
|
||||
<property name="row-spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Size</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="valign">baseline</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScale" id="size_scale">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="width-request">100</property>
|
||||
<property name="valign">baseline</property>
|
||||
<property name="adjustment">size_adjustment</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="size_entry">
|
||||
<property name="width-chars">4</property>
|
||||
<property name="max-width-chars">4</property>
|
||||
<property name="hexpand">0</property>
|
||||
<property name="valign">baseline</property>
|
||||
<signal name="activate" handler="basic_entry_activated"
|
||||
object="size_adjustment" swapped="false"/>
|
||||
<layout>
|
||||
<property name="column">2</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Letterspacing</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="valign">baseline</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScale">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="width-request">100</property>
|
||||
<property name="valign">baseline</property>
|
||||
<property name="adjustment">letterspacing_adjustment</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="letterspacing_entry">
|
||||
<property name="width-chars">4</property>
|
||||
<property name="max-width-chars">4</property>
|
||||
<property name="hexpand">0</property>
|
||||
<property name="valign">baseline</property>
|
||||
<signal name="activate" handler="basic_entry_activated"
|
||||
object="letterspacing_adjustment" swapped="false"/>
|
||||
<layout>
|
||||
<property name="column">2</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Line Height</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="valign">baseline</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScale">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="width-request">100</property>
|
||||
<property name="valign">baseline</property>
|
||||
<property name="adjustment">line_height_adjustment</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="line_height_entry">
|
||||
<property name="width-chars">4</property>
|
||||
<property name="max-width-chars">4</property>
|
||||
<property name="hexpand">0</property>
|
||||
<property name="valign">baseline</property>
|
||||
<signal name="activate" handler="basic_entry_activated"
|
||||
object="line_height_adjustment" swapped="false"/>
|
||||
<layout>
|
||||
<property name="column">2</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Foreground</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="valign">baseline</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColorButton" id="foreground">
|
||||
<property name="valign">baseline</property>
|
||||
<property name="rgba">black</property>
|
||||
<signal name="notify::rgba" handler="color_set_cb"/>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Background</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="valign">baseline</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">4</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColorButton" id="background">
|
||||
<property name="valign">baseline</property>
|
||||
<property name="rgba">white</property>
|
||||
<signal name="notify::rgba" handler="color_set_cb"/>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">4</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">object-flip-vertical-symbolic</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<style>
|
||||
<class name="circular"/>
|
||||
</style>
|
||||
<signal name="clicked" handler="swap_colors"/>
|
||||
<layout>
|
||||
<property name="column">2</property>
|
||||
<property name="row">3</property>
|
||||
<property name="row-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkExpander">
|
||||
<child type="label">
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">OpenType Features</property>
|
||||
<property name="margin-top">10</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<style>
|
||||
<class name="title-4"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="feature_list">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="script_lang">
|
||||
<property name="tooltip-text" translatable="yes">Language System</property>
|
||||
<property name="margin-top">10</property>
|
||||
<signal name="changed" handler="font_features_script_changed" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkExpander">
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="variations_heading">
|
||||
<property name="label" translatable="yes">Variation Axes</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="margin-top">10</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<style>
|
||||
<class name="title-4"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGrid" id="variations_grid">
|
||||
<property name="column-spacing">10</property>
|
||||
<property name="row-spacing">10</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkExpander">
|
||||
<child type="label">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Color Palettes</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="margin-top">10</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<style>
|
||||
<class name="title-4"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGrid" id="colors_grid">
|
||||
<property name="column-spacing">10</property>
|
||||
<property name="row-spacing">10</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="view"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<property name="margin-start">20</property>
|
||||
<property name="margin-end">20</property>
|
||||
<property name="margin-top">20</property>
|
||||
<property name="margin-bottom">20</property>
|
||||
<property name="spacing">20</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="swin">
|
||||
<property name="hscrollbar-policy">automatic</property>
|
||||
<property name="vscrollbar-policy">automatic</property>
|
||||
<property name="propagate-natural-height">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<style>
|
||||
<class name="font_features_background"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkStack" id="stack">
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">label</property>
|
||||
<property name="child">
|
||||
<object class="GtkLabel" id="label">
|
||||
<property name="wrap">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0</property>
|
||||
<property name="valign">start</property>
|
||||
<property name="selectable">1</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">entry</property>
|
||||
<property name="child">
|
||||
<object class="GtkTextView" id="entry">
|
||||
<property name="buffer">
|
||||
<object class="GtkTextBuffer">
|
||||
<property name="text">Grumpy wizards make toxic brew for the evil Queen and Jack. A quick movement of the enemy will jeopardize six gunboats. The job of waxing linoleum frequently peeves chintzy kids. My girl wove six dozen plaid jackets before she quit. Twelve ziggurats quickly jumped a finch box.
|
||||
|
||||
Разъяренный чтец эгоистично бьёт пятью жердями шустрого фехтовальщика. Наш банк вчера же выплатил Ф.Я. Эйхгольду комиссию за ценные вещи. Эх, чужак, общий съём цен шляп (юфть) – вдрызг! В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!
|
||||
|
||||
Τάχιστη αλώπηξ βαφής ψημένη γη, δρασκελίζει υπέρ νωθρού κυνός</property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="valign">fill</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="settings">
|
||||
<property name="wrap">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="valign">end</property>
|
||||
<property name="width-chars">50</property>
|
||||
<property name="max-width-chars">50</property>
|
||||
<property name="hexpand">1</property>
|
||||
<style>
|
||||
<class name="monospace"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">Alphabet</property>
|
||||
<signal name="clicked" handler="set_text_alphabet"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">Paragraph</property>
|
||||
<signal name="clicked" handler="set_text_paragraph"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="description">
|
||||
<property name="wrap">1</property>
|
||||
<property name="wrap-mode">char</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="valign">end</property>
|
||||
<property name="width-chars">50</property>
|
||||
<property name="max-width-chars">50</property>
|
||||
<property name="hexpand">1</property>
|
||||
<style>
|
||||
<class name="monospace"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<style>
|
||||
<class name="linked"/>
|
||||
</style>
|
||||
<property name="valign">end</property>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="plain_toggle">
|
||||
<property name="label" translatable="yes">Plain</property>
|
||||
<property name="active">1</property>
|
||||
<property name="valign">baseline</property>
|
||||
<signal name="toggled" handler="font_features_toggle_plain"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="waterfall_toggle">
|
||||
<property name="label" translatable="yes">Waterfall</property>
|
||||
<property name="valign">baseline</property>
|
||||
<property name="group">plain_toggle</property>
|
||||
<signal name="toggled" handler="font_features_toggle_plain"/>
|
||||
<signal name="notify::active" handler="font_features_notify_waterfall"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="edit_toggle">
|
||||
<property name="group">waterfall_toggle</property>
|
||||
<property name="icon-name">document-edit-symbolic</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">end</property>
|
||||
<signal name="clicked" handler="font_features_toggle_edit"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
static void
|
||||
insert_tags_for_attributes (GtkTextBuffer *buffer,
|
||||
PangoAttrIterator *iter,
|
||||
Pango2AttrIterator *iter,
|
||||
GtkTextIter *start,
|
||||
GtkTextIter *end)
|
||||
{
|
||||
@@ -27,13 +27,12 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
|
||||
GSList *attrs, *l;
|
||||
GtkTextTag *tag;
|
||||
char name[256];
|
||||
float fg_alpha, bg_alpha;
|
||||
|
||||
table = gtk_text_buffer_get_tag_table (buffer);
|
||||
|
||||
#define LANGUAGE_ATTR(attr_name) \
|
||||
{ \
|
||||
const char *language = pango_language_to_string (((PangoAttrLanguage*)attr)->value); \
|
||||
const char *language = pango2_language_to_string (pango2_attribute_get_language (attr)); \
|
||||
g_snprintf (name, 256, "language=%s", language); \
|
||||
tag = gtk_text_tag_table_lookup (table, name); \
|
||||
if (!tag) \
|
||||
@@ -48,7 +47,7 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
|
||||
|
||||
#define STRING_ATTR(attr_name) \
|
||||
{ \
|
||||
const char *string = ((PangoAttrString*)attr)->value; \
|
||||
const char *string = pango2_attribute_get_string (attr); \
|
||||
g_snprintf (name, 256, #attr_name "=%s", string); \
|
||||
tag = gtk_text_tag_table_lookup (table, name); \
|
||||
if (!tag) \
|
||||
@@ -63,7 +62,7 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
|
||||
|
||||
#define INT_ATTR(attr_name) \
|
||||
{ \
|
||||
int value = ((PangoAttrInt*)attr)->value; \
|
||||
int value = pango2_attribute_get_int (attr); \
|
||||
g_snprintf (name, 256, #attr_name "=%d", value); \
|
||||
tag = gtk_text_tag_table_lookup (table, name); \
|
||||
if (!tag) \
|
||||
@@ -78,8 +77,8 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
|
||||
|
||||
#define FONT_ATTR(attr_name) \
|
||||
{ \
|
||||
PangoFontDescription *desc = ((PangoAttrFontDesc*)attr)->desc; \
|
||||
char *str = pango_font_description_to_string (desc); \
|
||||
Pango2FontDescription *desc = pango2_attribute_get_font_desc (attr); \
|
||||
char *str = pango2_font_description_to_string (desc); \
|
||||
g_snprintf (name, 256, "font-desc=%s", str); \
|
||||
g_free (str); \
|
||||
tag = gtk_text_tag_table_lookup (table, name); \
|
||||
@@ -95,7 +94,7 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
|
||||
|
||||
#define FLOAT_ATTR(attr_name) \
|
||||
{ \
|
||||
float value = ((PangoAttrFloat*)attr)->value; \
|
||||
float value = pango2_attribute_get_float (attr); \
|
||||
g_snprintf (name, 256, #attr_name "=%g", value); \
|
||||
tag = gtk_text_tag_table_lookup (table, name); \
|
||||
if (!tag) \
|
||||
@@ -108,15 +107,14 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
|
||||
gtk_text_buffer_apply_tag (buffer, tag, start, end); \
|
||||
}
|
||||
|
||||
#define RGBA_ATTR(attr_name, alpha_value) \
|
||||
#define RGBA_ATTR(attr_name) \
|
||||
{ \
|
||||
PangoColor *color; \
|
||||
Pango2Color *color = pango2_attribute_get_color (attr); \
|
||||
GdkRGBA rgba; \
|
||||
color = &((PangoAttrColor*)attr)->color; \
|
||||
rgba.red = color->red / 65535.; \
|
||||
rgba.green = color->green / 65535.; \
|
||||
rgba.blue = color->blue / 65535.; \
|
||||
rgba.alpha = alpha_value; \
|
||||
rgba.alpha = color->alpha / 65535.; \
|
||||
char *str = gdk_rgba_to_string (&rgba); \
|
||||
g_snprintf (name, 256, #attr_name "=%s", str); \
|
||||
g_free (str); \
|
||||
@@ -144,173 +142,157 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
|
||||
gtk_text_buffer_apply_tag (buffer, tag, start, end); \
|
||||
}
|
||||
|
||||
fg_alpha = bg_alpha = 1.;
|
||||
|
||||
attrs = pango_attr_iterator_get_attrs (iter);
|
||||
attrs = pango2_attr_iterator_get_attrs (iter);
|
||||
for (l = attrs; l; l = l->next)
|
||||
{
|
||||
PangoAttribute *attr = l->data;
|
||||
Pango2Attribute *attr = l->data;
|
||||
|
||||
switch ((int)attr->klass->type)
|
||||
switch (pango2_attribute_type (attr))
|
||||
{
|
||||
case PANGO_ATTR_FOREGROUND_ALPHA:
|
||||
fg_alpha = ((PangoAttrInt*)attr)->value / 65535.;
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_BACKGROUND_ALPHA:
|
||||
bg_alpha = ((PangoAttrInt*)attr)->value / 65535.;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (l = attrs; l; l = l->next)
|
||||
{
|
||||
PangoAttribute *attr = l->data;
|
||||
|
||||
switch (attr->klass->type)
|
||||
{
|
||||
case PANGO_ATTR_LANGUAGE:
|
||||
case PANGO2_ATTR_LANGUAGE:
|
||||
LANGUAGE_ATTR (language);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_FAMILY:
|
||||
case PANGO2_ATTR_FAMILY:
|
||||
STRING_ATTR (family);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_STYLE:
|
||||
case PANGO2_ATTR_STYLE:
|
||||
INT_ATTR (style);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_WEIGHT:
|
||||
case PANGO2_ATTR_WEIGHT:
|
||||
INT_ATTR (weight);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_VARIANT:
|
||||
case PANGO2_ATTR_VARIANT:
|
||||
INT_ATTR (variant);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_STRETCH:
|
||||
case PANGO2_ATTR_STRETCH:
|
||||
INT_ATTR (stretch);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_SIZE:
|
||||
case PANGO2_ATTR_SIZE:
|
||||
INT_ATTR (size);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_FONT_DESC:
|
||||
case PANGO2_ATTR_FONT_DESC:
|
||||
FONT_ATTR (font-desc);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_FOREGROUND:
|
||||
RGBA_ATTR (foreground_rgba, fg_alpha);
|
||||
case PANGO2_ATTR_FOREGROUND:
|
||||
RGBA_ATTR (foreground_rgba);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_BACKGROUND:
|
||||
RGBA_ATTR (background_rgba, bg_alpha);
|
||||
case PANGO2_ATTR_BACKGROUND:
|
||||
RGBA_ATTR (background_rgba);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_UNDERLINE:
|
||||
case PANGO2_ATTR_UNDERLINE:
|
||||
INT_ATTR (underline);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_UNDERLINE_COLOR:
|
||||
RGBA_ATTR (underline_rgba, fg_alpha);
|
||||
case PANGO2_ATTR_UNDERLINE_COLOR:
|
||||
RGBA_ATTR (underline_rgba);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_OVERLINE:
|
||||
case PANGO2_ATTR_OVERLINE:
|
||||
INT_ATTR (overline);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_OVERLINE_COLOR:
|
||||
RGBA_ATTR (overline_rgba, fg_alpha);
|
||||
case PANGO2_ATTR_OVERLINE_COLOR:
|
||||
RGBA_ATTR (overline_rgba);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_STRIKETHROUGH:
|
||||
case PANGO2_ATTR_STRIKETHROUGH:
|
||||
INT_ATTR (strikethrough);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_STRIKETHROUGH_COLOR:
|
||||
RGBA_ATTR (strikethrough_rgba, fg_alpha);
|
||||
case PANGO2_ATTR_STRIKETHROUGH_COLOR:
|
||||
RGBA_ATTR (strikethrough_rgba);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_RISE:
|
||||
case PANGO2_ATTR_RISE:
|
||||
INT_ATTR (rise);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_SCALE:
|
||||
case PANGO2_ATTR_SCALE:
|
||||
FLOAT_ATTR (scale);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_FALLBACK:
|
||||
case PANGO2_ATTR_FALLBACK:
|
||||
INT_ATTR (fallback);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_LETTER_SPACING:
|
||||
case PANGO2_ATTR_LETTER_SPACING:
|
||||
INT_ATTR (letter_spacing);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_FONT_FEATURES:
|
||||
case PANGO2_ATTR_FONT_FEATURES:
|
||||
STRING_ATTR (font_features);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_ALLOW_BREAKS:
|
||||
case PANGO2_ATTR_ALLOW_BREAKS:
|
||||
INT_ATTR (allow_breaks);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_SHOW:
|
||||
case PANGO2_ATTR_SHOW:
|
||||
INT_ATTR (show_spaces);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_INSERT_HYPHENS:
|
||||
case PANGO2_ATTR_INSERT_HYPHENS:
|
||||
INT_ATTR (insert_hyphens);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_LINE_HEIGHT:
|
||||
case PANGO2_ATTR_LINE_HEIGHT:
|
||||
FLOAT_ATTR (line_height);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_ABSOLUTE_LINE_HEIGHT:
|
||||
case PANGO2_ATTR_ABSOLUTE_LINE_HEIGHT:
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_WORD:
|
||||
case PANGO2_ATTR_LINE_SPACING:
|
||||
INT_ATTR (pixels_inside_wrap);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_WORD:
|
||||
VOID_ATTR (word);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_SENTENCE:
|
||||
case PANGO2_ATTR_SENTENCE:
|
||||
VOID_ATTR (sentence);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_BASELINE_SHIFT:
|
||||
case PANGO2_ATTR_PARAGRAPH:
|
||||
VOID_ATTR (paragraph);
|
||||
break;
|
||||
|
||||
case PANGO2_ATTR_BASELINE_SHIFT:
|
||||
INT_ATTR (baseline_shift);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_FONT_SCALE:
|
||||
case PANGO2_ATTR_FONT_SCALE:
|
||||
INT_ATTR (font_scale);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_SHAPE:
|
||||
case PANGO_ATTR_ABSOLUTE_SIZE:
|
||||
case PANGO_ATTR_GRAVITY:
|
||||
case PANGO_ATTR_GRAVITY_HINT:
|
||||
case PANGO_ATTR_FOREGROUND_ALPHA:
|
||||
case PANGO_ATTR_BACKGROUND_ALPHA:
|
||||
case PANGO2_ATTR_ABSOLUTE_SIZE:
|
||||
case PANGO2_ATTR_GRAVITY:
|
||||
case PANGO2_ATTR_GRAVITY_HINT:
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_TEXT_TRANSFORM:
|
||||
case PANGO2_ATTR_TEXT_TRANSFORM:
|
||||
INT_ATTR (text_transform);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_INVALID:
|
||||
case PANGO2_ATTR_INVALID:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_slist_free_full (attrs, (GDestroyNotify)pango_attribute_destroy);
|
||||
g_slist_free_full (attrs, (GDestroyNotify)pango2_attribute_destroy);
|
||||
|
||||
#undef LANGUAGE_ATTR
|
||||
#undef STRING_ATTR
|
||||
@@ -329,9 +311,9 @@ typedef struct
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter iter;
|
||||
GtkTextMark *mark;
|
||||
PangoAttrList *attributes;
|
||||
Pango2AttrList *attributes;
|
||||
char *text;
|
||||
PangoAttrIterator *attr;
|
||||
Pango2AttrIterator *attr;
|
||||
} MarkupData;
|
||||
|
||||
static void
|
||||
@@ -340,8 +322,8 @@ free_markup_data (MarkupData *mdata)
|
||||
g_free (mdata->markup);
|
||||
g_clear_pointer (&mdata->parser, g_markup_parse_context_free);
|
||||
gtk_text_buffer_delete_mark (mdata->buffer, mdata->mark);
|
||||
g_clear_pointer (&mdata->attr, pango_attr_iterator_destroy);
|
||||
g_clear_pointer (&mdata->attributes, pango_attr_list_unref);
|
||||
g_clear_pointer (&mdata->attr, pango2_attr_iterator_destroy);
|
||||
g_clear_pointer (&mdata->attributes, pango2_attr_list_unref);
|
||||
g_free (mdata->text);
|
||||
g_object_unref (mdata->buffer);
|
||||
g_free (mdata);
|
||||
@@ -367,7 +349,7 @@ insert_markup_idle (gpointer data)
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
pango_attr_iterator_range (mdata->attr, &start, &end);
|
||||
pango2_attr_iterator_range (mdata->attr, &start, &end);
|
||||
|
||||
if (end == G_MAXINT) /* last chunk */
|
||||
end = start - 1; /* resulting in -1 to be passed to _insert */
|
||||
@@ -380,7 +362,7 @@ insert_markup_idle (gpointer data)
|
||||
|
||||
gtk_text_buffer_get_iter_at_mark (mdata->buffer, &mdata->iter, mdata->mark);
|
||||
}
|
||||
while (pango_attr_iterator_next (mdata->attr));
|
||||
while (pango2_attr_iterator_next (mdata->attr));
|
||||
|
||||
free_markup_data (mdata);
|
||||
return G_SOURCE_REMOVE;
|
||||
@@ -416,7 +398,7 @@ parse_markup_idle (gpointer data)
|
||||
mdata->pos += 4096;
|
||||
} while (mdata->pos < mdata->len);
|
||||
|
||||
if (!pango_markup_parser_finish (mdata->parser,
|
||||
if (!pango2_markup_parser_finish (mdata->parser,
|
||||
&mdata->attributes,
|
||||
&mdata->text,
|
||||
NULL,
|
||||
@@ -435,7 +417,7 @@ parse_markup_idle (gpointer data)
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
mdata->attr = pango_attr_list_get_iterator (mdata->attributes);
|
||||
mdata->attr = pango2_attr_list_get_iterator (mdata->attributes);
|
||||
insert_markup_idle (data);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
@@ -461,7 +443,7 @@ insert_markup (GtkTextBuffer *buffer,
|
||||
data->markup = markup;
|
||||
data->len = len;
|
||||
|
||||
data->parser = pango_markup_parser_new (0);
|
||||
data->parser = pango2_markup_parser_new (0);
|
||||
data->pos = 0;
|
||||
|
||||
/* create mark with right gravity */
|
||||
|
||||
@@ -25,7 +25,7 @@ static GtkWidget *show_extents = NULL;
|
||||
static GtkWidget *show_pixels = NULL;
|
||||
static GtkWidget *show_outlines = NULL;
|
||||
|
||||
static PangoContext *context;
|
||||
static Pango2Context *context;
|
||||
|
||||
static int scale = 7;
|
||||
static double pixel_alpha = 1.0;
|
||||
@@ -35,9 +35,9 @@ static void
|
||||
update_image (void)
|
||||
{
|
||||
const char *text;
|
||||
PangoFontDescription *desc;
|
||||
PangoLayout *layout;
|
||||
PangoRectangle ink, logical;
|
||||
Pango2FontDescription *desc;
|
||||
Pango2Layout *layout;
|
||||
Pango2Rectangle ink, logical;
|
||||
int baseline;
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
@@ -56,7 +56,7 @@ update_image (void)
|
||||
text = gtk_editable_get_text (GTK_EDITABLE (entry));
|
||||
desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (font_button));
|
||||
|
||||
fopt = cairo_font_options_copy (pango_cairo_context_get_font_options (context));
|
||||
fopt = cairo_font_options_copy (pango2_cairo_context_get_font_options (context));
|
||||
|
||||
hint = gtk_combo_box_get_active_id (GTK_COMBO_BOX (hinting));
|
||||
hintstyle = CAIRO_HINT_STYLE_DEFAULT;
|
||||
@@ -85,20 +85,20 @@ update_image (void)
|
||||
antialias = CAIRO_ANTIALIAS_NONE;
|
||||
cairo_font_options_set_antialias (fopt, antialias);
|
||||
|
||||
pango_context_set_round_glyph_positions (context, hintmetrics == CAIRO_HINT_METRICS_ON);
|
||||
pango_cairo_context_set_font_options (context, fopt);
|
||||
pango2_context_set_round_glyph_positions (context, hintmetrics == CAIRO_HINT_METRICS_ON);
|
||||
pango2_cairo_context_set_font_options (context, fopt);
|
||||
cairo_font_options_destroy (fopt);
|
||||
pango_context_changed (context);
|
||||
pango2_context_changed (context);
|
||||
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (text_radio)))
|
||||
{
|
||||
layout = pango_layout_new (context);
|
||||
pango_layout_set_font_description (layout, desc);
|
||||
pango_layout_set_text (layout, text, -1);
|
||||
pango_layout_get_extents (layout, &ink, &logical);
|
||||
baseline = pango_layout_get_baseline (layout);
|
||||
layout = pango2_layout_new (context);
|
||||
pango2_layout_set_font_description (layout, desc);
|
||||
pango2_layout_set_text (layout, text, -1);
|
||||
pango2_lines_get_extents (pango2_layout_get_lines (layout), &ink, &logical);
|
||||
baseline = pango2_lines_get_baseline (pango2_layout_get_lines (layout));
|
||||
|
||||
pango_extents_to_pixels (&ink, NULL);
|
||||
pango2_extents_to_pixels (&ink, NULL);
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, ink.width + 20, ink.height + 20);
|
||||
cr = cairo_create (surface);
|
||||
@@ -108,9 +108,9 @@ update_image (void)
|
||||
cairo_set_source_rgba (cr, 0, 0, 0, pixel_alpha);
|
||||
|
||||
cairo_move_to (cr, 10, 10);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
pango2_cairo_show_layout (cr, layout);
|
||||
|
||||
pango_cairo_layout_path (cr, layout);
|
||||
pango2_cairo_layout_path (cr, layout);
|
||||
path = cairo_copy_path (cr);
|
||||
|
||||
cairo_destroy (cr);
|
||||
@@ -154,15 +154,15 @@ update_image (void)
|
||||
cairo_set_source_rgb (cr, 0, 0, 1);
|
||||
|
||||
cairo_rectangle (cr,
|
||||
scale * (10 + pango_units_to_double (logical.x)) - 0.5,
|
||||
scale * (10 + pango_units_to_double (logical.y)) - 0.5,
|
||||
scale * pango_units_to_double (logical.width) + 1,
|
||||
scale * pango_units_to_double (logical.height) + 1);
|
||||
scale * (10 + pango2_units_to_double (logical.x)) - 0.5,
|
||||
scale * (10 + pango2_units_to_double (logical.y)) - 0.5,
|
||||
scale * pango2_units_to_double (logical.width) + 1,
|
||||
scale * pango2_units_to_double (logical.height) + 1);
|
||||
cairo_stroke (cr);
|
||||
cairo_move_to (cr, scale * (10 + pango_units_to_double (logical.x)) - 0.5,
|
||||
scale * (10 + pango_units_to_double (baseline)) - 0.5);
|
||||
cairo_line_to (cr, scale * (10 + pango_units_to_double (logical.x + logical.width)) + 1,
|
||||
scale * (10 + pango_units_to_double (baseline)) - 0.5);
|
||||
cairo_move_to (cr, scale * (10 + pango2_units_to_double (logical.x)) - 0.5,
|
||||
scale * (10 + pango2_units_to_double (baseline)) - 0.5);
|
||||
cairo_line_to (cr, scale * (10 + pango2_units_to_double (logical.x + logical.width)) + 1,
|
||||
scale * (10 + pango2_units_to_double (baseline)) - 0.5);
|
||||
cairo_stroke (cr);
|
||||
cairo_set_source_rgb (cr, 1, 0, 0);
|
||||
cairo_rectangle (cr,
|
||||
@@ -206,9 +206,10 @@ update_image (void)
|
||||
}
|
||||
else
|
||||
{
|
||||
PangoLayoutIter *iter;
|
||||
PangoLayoutRun *run;
|
||||
PangoGlyphInfo *g;
|
||||
Pango2LineIter *iter;
|
||||
Pango2Run *run;
|
||||
Pango2GlyphString *glyphs;
|
||||
Pango2GlyphInfo *g;
|
||||
int i, j;
|
||||
GString *str;
|
||||
gunichar ch;
|
||||
@@ -226,43 +227,44 @@ update_image (void)
|
||||
g_string_append_unichar (str, 0x200c);
|
||||
}
|
||||
|
||||
layout = pango_layout_new (context);
|
||||
pango_layout_set_font_description (layout, desc);
|
||||
pango_layout_set_text (layout, str->str, -1);
|
||||
layout = pango2_layout_new (context);
|
||||
pango2_layout_set_font_description (layout, desc);
|
||||
pango2_layout_set_text (layout, str->str, -1);
|
||||
g_string_free (str, TRUE);
|
||||
pango_layout_get_extents (layout, &ink, &logical);
|
||||
pango_extents_to_pixels (&logical, NULL);
|
||||
pango2_lines_get_extents (pango2_layout_get_lines (layout), &ink, &logical);
|
||||
pango2_extents_to_pixels (&logical, NULL);
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, logical.width * 3 / 2, 4*logical.height);
|
||||
cr = cairo_create (surface);
|
||||
cairo_set_source_rgb (cr, 1, 1, 1);
|
||||
cairo_paint (cr);
|
||||
|
||||
iter = pango_layout_get_iter (layout);
|
||||
run = pango_layout_iter_get_run (iter);
|
||||
iter = pango2_layout_get_iter (layout);
|
||||
run = pango2_line_iter_get_run (iter);
|
||||
glyphs = pango2_run_get_glyphs (run);
|
||||
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
g = &(run->glyphs->glyphs[2*i]);
|
||||
g->geometry.width = PANGO_UNITS_ROUND (g->geometry.width * 3 / 2);
|
||||
g = &(glyphs->glyphs[2*i]);
|
||||
g->geometry.width = PANGO2_UNITS_ROUND (g->geometry.width * 3 / 2);
|
||||
}
|
||||
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
g = &(run->glyphs->glyphs[2*i]);
|
||||
g->geometry.x_offset = i * (PANGO_SCALE / 4);
|
||||
g->geometry.y_offset = j * (PANGO_SCALE / 4);
|
||||
g = &(glyphs->glyphs[2*i]);
|
||||
g->geometry.x_offset = i * (PANGO2_SCALE / 4);
|
||||
g->geometry.y_offset = j * (PANGO2_SCALE / 4);
|
||||
}
|
||||
|
||||
cairo_move_to (cr, 0, j * logical.height);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
pango2_cairo_show_layout (cr, layout);
|
||||
}
|
||||
|
||||
cairo_destroy (cr);
|
||||
pango_layout_iter_free (iter);
|
||||
pango2_line_iter_free (iter);
|
||||
g_object_unref (layout);
|
||||
|
||||
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, cairo_image_surface_get_width (surface), cairo_image_surface_get_height (surface));
|
||||
@@ -275,7 +277,7 @@ update_image (void)
|
||||
|
||||
g_object_unref (pixbuf2);
|
||||
|
||||
pango_font_description_free (desc);
|
||||
pango2_font_description_free (desc);
|
||||
}
|
||||
|
||||
static gboolean fading = FALSE;
|
||||
|
||||
@@ -23,7 +23,7 @@ do_headerbar (GtkWidget *do_widget)
|
||||
{
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Welcome to Facebook - Log in, sign up or learn more");
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Welcome to the Hotel California");
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
|
||||
@@ -31,6 +31,7 @@ do_headerbar (GtkWidget *do_widget)
|
||||
header = gtk_header_bar_new ();
|
||||
|
||||
button = gtk_button_new_from_icon_name ("mail-send-receive-symbolic");
|
||||
gtk_widget_set_tooltip_text (button, "Check out");
|
||||
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), button);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
|
||||
@@ -29,7 +29,7 @@ insert_link (GtkTextBuffer *buffer,
|
||||
|
||||
tag = gtk_text_buffer_create_tag (buffer, NULL,
|
||||
"foreground", "blue",
|
||||
"underline", PANGO_UNDERLINE_SINGLE,
|
||||
"underline", PANGO2_LINE_STYLE_SOLID,
|
||||
NULL);
|
||||
g_object_set_data (G_OBJECT (tag), "page", GINT_TO_POINTER (page));
|
||||
gtk_text_buffer_insert_with_tags (buffer, iter, text, -1, tag, NULL);
|
||||
@@ -72,8 +72,8 @@ show_page (GtkTextView *text_view,
|
||||
buffer = gtk_text_view_get_buffer (text_view);
|
||||
|
||||
bold = gtk_text_buffer_create_tag (buffer, NULL,
|
||||
"weight", PANGO_WEIGHT_BOLD,
|
||||
"scale", PANGO_SCALE_X_LARGE,
|
||||
"weight", PANGO2_WEIGHT_BOLD,
|
||||
"scale", PANGO2_SCALE_X_LARGE,
|
||||
NULL);
|
||||
mono = gtk_text_buffer_create_tag (buffer, NULL,
|
||||
"family", "monospace",
|
||||
|
||||
@@ -123,11 +123,11 @@ populate_emoji_text (void)
|
||||
for (int i = 0; i < 500; i++)
|
||||
{
|
||||
if (i % 2)
|
||||
g_string_append (s, "<span underline=\"single\" underline_color=\"red\">x</span>");
|
||||
g_string_append (s, "<span underline=\"solid\" underline_color=\"red\">x</span>");
|
||||
for (int j = 0; j < 30; j++)
|
||||
{
|
||||
g_string_append (s, "💓");
|
||||
g_string_append (s, "<span underline=\"single\" underline_color=\"red\">x</span>");
|
||||
g_string_append (s, "<span underline=\"solid\" underline_color=\"red\">x</span>");
|
||||
}
|
||||
g_string_append (s, "\n");
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param)
|
||||
gint i;
|
||||
const LCTYPE iso639_lctypes[] = { LOCALE_SISO639LANGNAME, LOCALE_SISO639LANGNAME2 };
|
||||
GHashTable *ht_scripts_langs = (GHashTable *) param;
|
||||
PangoLanguage *lang;
|
||||
Pango2Language *lang;
|
||||
|
||||
gint langname_size, locale_abbrev_size;
|
||||
langname_size = GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, 0);
|
||||
@@ -60,7 +60,7 @@ get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param)
|
||||
langname = g_utf16_to_utf8 (langname_w, -1, NULL, NULL, NULL);
|
||||
locale = g_utf16_to_utf8 (locale_w, -1, NULL, NULL, NULL);
|
||||
p = strchr (locale, '-');
|
||||
lang = pango_language_from_string (locale);
|
||||
lang = pango2_language_from_string (locale);
|
||||
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
|
||||
g_hash_table_insert (ht_scripts_langs, lang, langname);
|
||||
|
||||
@@ -77,7 +77,7 @@ get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param)
|
||||
GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, locale_abbrev_size);
|
||||
|
||||
locale_abbrev = g_utf16_to_utf8 (locale_abbrev_w, -1, NULL, NULL, NULL);
|
||||
lang = pango_language_from_string (locale_abbrev);
|
||||
lang = pango2_language_from_string (locale_abbrev);
|
||||
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
|
||||
g_hash_table_insert (ht_scripts_langs, lang, langname);
|
||||
|
||||
@@ -218,22 +218,22 @@ languages_parse_start_tag (GMarkupParseContext *ctx,
|
||||
|
||||
if (ccode != NULL)
|
||||
g_hash_table_insert (language_map,
|
||||
pango_language_from_string (ccode),
|
||||
pango2_language_from_string (ccode),
|
||||
g_strdup (display_name));
|
||||
|
||||
if (ccode_longB != NULL)
|
||||
g_hash_table_insert (language_map,
|
||||
pango_language_from_string (ccode_longB),
|
||||
pango2_language_from_string (ccode_longB),
|
||||
g_strdup (display_name));
|
||||
|
||||
if (ccode_longT != NULL)
|
||||
g_hash_table_insert (language_map,
|
||||
pango_language_from_string (ccode_longT),
|
||||
pango2_language_from_string (ccode_longT),
|
||||
g_strdup (display_name));
|
||||
|
||||
if (ccode_id != NULL)
|
||||
g_hash_table_insert (language_map,
|
||||
pango_language_from_string (ccode_id),
|
||||
pango2_language_from_string (ccode_id),
|
||||
g_strdup (display_name));
|
||||
|
||||
g_free (display_name);
|
||||
@@ -295,7 +295,7 @@ languages_init (void)
|
||||
}
|
||||
|
||||
const char *
|
||||
get_language_name (PangoLanguage *language)
|
||||
get_language_name (Pango2Language *language)
|
||||
{
|
||||
languages_init ();
|
||||
|
||||
@@ -311,5 +311,5 @@ get_language_name_for_tag (guint32 tag)
|
||||
lang = hb_ot_tag_to_language (tag);
|
||||
s = hb_language_to_string (lang);
|
||||
|
||||
return get_language_name (pango_language_from_string (s));
|
||||
return get_language_name (pango2_language_from_string (s));
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#ifndef LANGUAGE_NAMES_H
|
||||
#define LANGUAGE_NAMES_H
|
||||
|
||||
#include <pango/pango.h>
|
||||
#include <pango2/pango.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
const char * get_language_name (PangoLanguage *language);
|
||||
const char * get_language_name (Pango2Language *language);
|
||||
const char * get_language_name_for_tag (guint32 tag);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -66,15 +66,13 @@ do_links (GtkWidget *do_widget)
|
||||
"as hyperlinks, which can be clicked "
|
||||
"or activated via <a href=\"keynav\">keynav</a> "
|
||||
"and they work fine with other markup, like when "
|
||||
"searching on <a href=\"http://www.google.com/\">"
|
||||
"<span color=\"#0266C8\">G</span><span color=\"#F90101\">o</span>"
|
||||
"<span color=\"#F2B50F\">o</span><span color=\"#0266C8\">g</span>"
|
||||
"<span color=\"#00933B\">l</span><span color=\"#F90101\">e</span>"
|
||||
"</a>.");
|
||||
"linking to <a href=\"http://www.flathub.org/\"><b>"
|
||||
"<span letter_spacing=\"1024\" underline=\"none\" color=\"pink\" background=\"darkslategray\">Flathub</span>"
|
||||
"</b></a>.");
|
||||
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_max_width_chars (GTK_LABEL (label), 40);
|
||||
gtk_label_set_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_wrap_mode (GTK_LABEL (label), PANGO_WRAP_WORD);
|
||||
gtk_label_set_wrap_mode (GTK_LABEL (label), PANGO2_WRAP_WORD);
|
||||
g_signal_connect (label, "activate-link", G_CALLBACK (activate_link), NULL);
|
||||
gtk_widget_set_margin_start (label, 20);
|
||||
gtk_widget_set_margin_end (label, 20);
|
||||
|
||||
@@ -42,8 +42,7 @@ do_listbox_controls (GtkWidget *do_widget)
|
||||
GtkBuilder *builder;
|
||||
|
||||
scope = gtk_builder_cscope_new ();
|
||||
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope),
|
||||
"row_activated", G_CALLBACK (row_activated));
|
||||
gtk_builder_cscope_add_callback (scope, row_activated);
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_set_scope (builder, scope);
|
||||
|
||||
|
||||
@@ -758,15 +758,15 @@ setup_number_item (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *item)
|
||||
{
|
||||
GtkWidget *label;
|
||||
PangoAttrList *attrs;
|
||||
Pango2AttrList *attrs;
|
||||
|
||||
label = gtk_label_new ("");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 1);
|
||||
|
||||
attrs = pango_attr_list_new ();
|
||||
pango_attr_list_insert (attrs, pango_attr_font_features_new ("tnum"));
|
||||
attrs = pango2_attr_list_new ();
|
||||
pango2_attr_list_insert (attrs, pango2_attr_font_features_new ("tnum"));
|
||||
gtk_label_set_attributes (GTK_LABEL (label), attrs);
|
||||
pango_attr_list_unref (attrs);
|
||||
pango2_attr_list_unref (attrs);
|
||||
|
||||
gtk_list_item_set_child (item, label);
|
||||
}
|
||||
@@ -862,7 +862,7 @@ do_listview_colors (GtkWidget *do_widget)
|
||||
GtkExpression *expression;
|
||||
GtkWidget *button;
|
||||
GtkWidget *label;
|
||||
PangoAttrList *attrs;
|
||||
Pango2AttrList *attrs;
|
||||
char *string;
|
||||
guint len;
|
||||
GtkWidget *selection_view;
|
||||
@@ -990,10 +990,10 @@ do_listview_colors (GtkWidget *do_widget)
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), button);
|
||||
|
||||
label = gtk_label_new ("0 /");
|
||||
attrs = pango_attr_list_new ();
|
||||
pango_attr_list_insert (attrs, pango_attr_font_features_new ("tnum"));
|
||||
attrs = pango2_attr_list_new ();
|
||||
pango2_attr_list_insert (attrs, pango2_attr_font_features_new ("tnum"));
|
||||
gtk_label_set_attributes (GTK_LABEL (label), attrs);
|
||||
pango_attr_list_unref (attrs);
|
||||
pango2_attr_list_unref (attrs);
|
||||
string = g_strdup_printf ("%'u", 4096);
|
||||
len = g_utf8_strlen (string, -1);
|
||||
g_free (string);
|
||||
|
||||
@@ -356,10 +356,10 @@ do_listview_settings (GtkWidget *do_widget)
|
||||
g_type_ensure (SETTINGS_TYPE_KEY);
|
||||
|
||||
scope = gtk_builder_cscope_new ();
|
||||
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "search_enabled", (GCallback)search_enabled);
|
||||
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "search_changed", (GCallback)search_changed);
|
||||
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "stop_search", (GCallback)stop_search);
|
||||
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "item_value_changed", (GCallback)item_value_changed);
|
||||
gtk_builder_cscope_add_callback (scope, search_enabled);
|
||||
gtk_builder_cscope_add_callback (scope, search_changed);
|
||||
gtk_builder_cscope_add_callback (scope, stop_search);
|
||||
gtk_builder_cscope_add_callback (scope, item_value_changed);
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_set_scope (builder, scope);
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include "script-names.h"
|
||||
#include "unicode-names.h"
|
||||
#include "simplelabel.h"
|
||||
|
||||
|
||||
#define UCD_TYPE_ITEM (ucd_item_get_type ())
|
||||
@@ -103,9 +102,7 @@ setup_centered_label (GtkSignalListItemFactory *factory,
|
||||
GObject *listitem)
|
||||
{
|
||||
GtkWidget *label;
|
||||
label = simple_label_new ();
|
||||
simple_label_set_min_chars (SIMPLE_LABEL (label), 3);
|
||||
simple_label_set_nat_chars (SIMPLE_LABEL (label), 20);
|
||||
label = gtk_label_new ("");
|
||||
gtk_list_item_set_child (GTK_LIST_ITEM (listitem), label);
|
||||
}
|
||||
|
||||
@@ -114,9 +111,8 @@ setup_label (GtkSignalListItemFactory *factory,
|
||||
GObject *listitem)
|
||||
{
|
||||
GtkWidget *label;
|
||||
label = simple_label_new ();
|
||||
simple_label_set_min_chars (SIMPLE_LABEL (label), 3);
|
||||
simple_label_set_nat_chars (SIMPLE_LABEL (label), 20);
|
||||
label = gtk_label_new ("");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_list_item_set_child (GTK_LIST_ITEM (listitem), label);
|
||||
}
|
||||
|
||||
@@ -125,9 +121,10 @@ setup_ellipsizing_label (GtkSignalListItemFactory *factory,
|
||||
GObject *listitem)
|
||||
{
|
||||
GtkWidget *label;
|
||||
label = simple_label_new ();
|
||||
simple_label_set_min_chars (SIMPLE_LABEL (label), 3);
|
||||
simple_label_set_nat_chars (SIMPLE_LABEL (label), 20);
|
||||
label = gtk_label_new ("");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO2_ELLIPSIZE_END);
|
||||
gtk_label_set_width_chars (GTK_LABEL (label), 20);
|
||||
gtk_list_item_set_child (GTK_LIST_ITEM (listitem), label);
|
||||
}
|
||||
|
||||
@@ -145,7 +142,7 @@ bind_codepoint (GtkSignalListItemFactory *factory,
|
||||
codepoint = ucd_item_get_codepoint (UCD_ITEM (item));
|
||||
|
||||
g_snprintf (buffer, 10, "%#06x", codepoint);
|
||||
simple_label_set_text (SIMPLE_LABEL (label), buffer);
|
||||
gtk_label_set_label (GTK_LABEL (label), buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -164,7 +161,7 @@ bind_char (GtkSignalListItemFactory *factory,
|
||||
if (g_unichar_isprint (codepoint))
|
||||
g_unichar_to_utf8 (codepoint, buffer);
|
||||
|
||||
simple_label_set_text (SIMPLE_LABEL (label), buffer);
|
||||
gtk_label_set_label (GTK_LABEL (label), buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -179,7 +176,7 @@ bind_name (GtkSignalListItemFactory *factory,
|
||||
item = gtk_list_item_get_item (GTK_LIST_ITEM (listitem));
|
||||
name = ucd_item_get_name (UCD_ITEM (item));
|
||||
|
||||
simple_label_set_text (SIMPLE_LABEL (label), name);
|
||||
gtk_label_set_label (GTK_LABEL (label), name);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -194,7 +191,7 @@ bind_type (GtkSignalListItemFactory *factory,
|
||||
item = gtk_list_item_get_item (GTK_LIST_ITEM (listitem));
|
||||
codepoint = ucd_item_get_codepoint (UCD_ITEM (item));
|
||||
|
||||
simple_label_set_text (SIMPLE_LABEL (label), get_unicode_type_name (g_unichar_type (codepoint)));
|
||||
gtk_label_set_label (GTK_LABEL (label), get_unicode_type_name (g_unichar_type (codepoint)));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -209,7 +206,7 @@ bind_break_type (GtkSignalListItemFactory *factory,
|
||||
item = gtk_list_item_get_item (GTK_LIST_ITEM (listitem));
|
||||
codepoint = ucd_item_get_codepoint (UCD_ITEM (item));
|
||||
|
||||
simple_label_set_text (SIMPLE_LABEL (label), get_break_type_name (g_unichar_break_type (codepoint)));
|
||||
gtk_label_set_label (GTK_LABEL (label), get_break_type_name (g_unichar_break_type (codepoint)));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -224,7 +221,7 @@ bind_combining_class (GtkSignalListItemFactory *factory,
|
||||
item = gtk_list_item_get_item (GTK_LIST_ITEM (listitem));
|
||||
codepoint = ucd_item_get_codepoint (UCD_ITEM (item));
|
||||
|
||||
simple_label_set_text (SIMPLE_LABEL (label), get_combining_class_name (g_unichar_combining_class (codepoint)));
|
||||
gtk_label_set_label (GTK_LABEL (label), get_combining_class_name (g_unichar_combining_class (codepoint)));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -241,7 +238,7 @@ bind_script (GtkSignalListItemFactory *factory,
|
||||
codepoint = ucd_item_get_codepoint (UCD_ITEM (item));
|
||||
script = g_unichar_get_script (codepoint);
|
||||
|
||||
simple_label_set_text (SIMPLE_LABEL (label), get_script_name (script));
|
||||
gtk_label_set_label (GTK_LABEL (label), get_script_name (script));
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Lists/Words
|
||||
* #Keywords: GtkListView, GtkFilterListModel
|
||||
* #Keywords: GtkListView, GtkFilterListModel, GtkInscription
|
||||
*
|
||||
* This demo shows filtering a long list - of words.
|
||||
*
|
||||
@@ -17,10 +17,9 @@ const char *factory_text =
|
||||
"<interface>\n"
|
||||
" <template class='GtkListItem'>\n"
|
||||
" <property name='child'>\n"
|
||||
" <object class='GtkLabel'>\n"
|
||||
" <property name='ellipsize'>end</property>\n"
|
||||
" <object class='GtkInscription'>\n"
|
||||
" <property name='xalign'>0</property>\n"
|
||||
" <binding name='label'>\n"
|
||||
" <binding name='text'>\n"
|
||||
" <lookup name='string' type='GtkStringObject'>\n"
|
||||
" <lookup name='item'>GtkListItem</lookup>\n"
|
||||
" </lookup>\n"
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</binding>
|
||||
<property name="child">
|
||||
<object class="GtkLabel">
|
||||
<property name="halign">start</property>
|
||||
<binding name="label">
|
||||
<object class="GtkInscription">
|
||||
<property name="hexpand">1</property>
|
||||
<binding name="text">
|
||||
<lookup name="title" type="GtkDemo">
|
||||
<lookup name="item">expander</lookup>
|
||||
</lookup>
|
||||
|
||||
@@ -190,8 +190,8 @@ activate_about (GSimpleAction *action,
|
||||
glib_major_version,
|
||||
glib_minor_version,
|
||||
glib_micro_version);
|
||||
g_string_append_printf (s, "\tPango\t%s\n",
|
||||
pango_version_string ());
|
||||
g_string_append_printf (s, "\tPango2\t%s\n",
|
||||
pango2_version_string ());
|
||||
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
|
||||
@@ -7,9 +7,9 @@ Text weights: <span weight="thin">thin</span> <span weight="light">light</span>
|
||||
|
||||
Text <span color="gray">c<span color="green">o</span>l<span color="tomato">o</span>rs</span> and <span background="pink">backgrounds</span>
|
||||
|
||||
Colorful <span underline="low" underline-color="blue"><span underline="double" underline-color="red">under</span>lines</span> and <span background="pink"><span underline="error">mo</span><span underline="error" underline-color="green">re</span></span>
|
||||
Colorful <span underline_position="under" underline-color="blue"><span underline="double" underline-color="red">under</span>lines</span> and <span background="pink"><span underline="wavy">mo</span><span underline="wavy" underline-color="green">re</span></span>
|
||||
|
||||
Colorful <span strikethrough="true" strikethrough-color="magenta">strikethroughs</span> and <span overline="single" overline_color="green">overlines</span>
|
||||
Colorful <span strikethrough="solid" strikethrough-color="magenta">strikethroughs</span> and <span overline="solid" overline_color="green">overlines</span>
|
||||
|
||||
Superscripts and subscripts: 𝜀<span rise="-6000" size="x-small" font_desc="italic">0</span> = 𝜔<span rise="8000" size="smaller">𝜔<span rise="14000" size="smaller">𝜔<span rise="20000">.<span rise="23000">.<span rise="26000">.</span></span></span></span></span>
|
||||
|
||||
@@ -19,7 +19,7 @@ OpenType font features: <span font_desc="sans regular" font_features="dlig=0">fe
|
||||
|
||||
Shortcuts: <tt>Monospace</tt> – <b>Bold</b> – <i>Italic</i> – <big>Big</big> – <small>Small</small> – <u>Underlined</u> – <s>Strikethrough</s> – Super<sup>script</sup> – Sub<sub>script</sub>
|
||||
|
||||
hyphenation algorithm is a <span allow_breaks="false" style="italic">set of rules</span>, especially one codified for implementation in a computer program, that decides at which points a word can be broken over two lines with a hyphen. For example, a hyphenation algorithm might decide that impeachment can be broken as impeach‧ment or im‧peachment but not impe‧achment.
|
||||
A hyphenation algorithm is a <span allow_breaks="false" style="italic">set of rules</span>, especially one codified for implementation in a computer program, that decides at which points a word can be broken over two lines with a hyphen. For example, a hyphenation algorithm might decide that impeachment can be broken as impeach‧ment or im‧peachment but not impe‧achment.
|
||||
|
||||
<span insert_hyphens="false">one/two three/four five/six seven/eight nine/ten</span>
|
||||
|
||||
|
||||
@@ -73,8 +73,9 @@ demos = files([
|
||||
'peg_solitaire.c',
|
||||
'pickers.c',
|
||||
'printing.c',
|
||||
'read_more.c',
|
||||
'revealer.c',
|
||||
'rotated_text.c',
|
||||
#'rotated_text.c', FIXME
|
||||
'scale.c',
|
||||
'search_entry.c',
|
||||
'search_entry2.c',
|
||||
@@ -130,7 +131,6 @@ extra_demo_sources = files([
|
||||
'unicode-names.c',
|
||||
'suggestionentry.c',
|
||||
'language-names.c',
|
||||
'simplelabel.c',
|
||||
])
|
||||
|
||||
if os_unix
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* #Keywords: GtkColorChooser, GtkFontChooser, GtkApplicationChooser
|
||||
*
|
||||
* These widgets are mainly intended for use in preference dialogs.
|
||||
* They allow to select colors, fonts, directories and applications.
|
||||
* They allow to select colors, fonts and applications.
|
||||
*
|
||||
* This demo shows both the default appearance for these dialogs,
|
||||
* as well as some of the customizations that are possible.
|
||||
@@ -11,8 +11,8 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static gboolean
|
||||
filter_font_cb (const PangoFontFamily *family,
|
||||
const PangoFontFace *face,
|
||||
filter_font_cb (const Pango2FontFamily *family,
|
||||
const Pango2FontFace *face,
|
||||
gpointer data)
|
||||
{
|
||||
const char *alias_families[] = {
|
||||
@@ -26,9 +26,15 @@ filter_font_cb (const PangoFontFamily *family,
|
||||
};
|
||||
const char *family_name;
|
||||
|
||||
family_name = pango_font_family_get_name (PANGO_FONT_FAMILY (family));
|
||||
family_name = pango2_font_family_get_name ((Pango2FontFamily *)family);
|
||||
|
||||
return g_strv_contains (alias_families, family_name);
|
||||
for (int i = 0; alias_families[i]; i++)
|
||||
{
|
||||
if (g_ascii_strcasecmp (alias_families[i], family_name) == 0)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#define COLOR(r,g,b) { r/255., g/255., b/255., 1.0 }
|
||||
|
||||
@@ -59,11 +59,11 @@ draw_page (GtkPrintOperation *operation,
|
||||
{
|
||||
PrintData *data = (PrintData *)user_data;
|
||||
cairo_t *cr;
|
||||
PangoLayout *layout;
|
||||
int text_width, text_height;
|
||||
Pango2Layout *layout;
|
||||
Pango2Rectangle ext;
|
||||
double width;
|
||||
int line, i;
|
||||
PangoFontDescription *desc;
|
||||
Pango2FontDescription *desc;
|
||||
char *page_str;
|
||||
|
||||
cr = gtk_print_context_get_cairo_context (context);
|
||||
@@ -80,47 +80,50 @@ draw_page (GtkPrintOperation *operation,
|
||||
|
||||
layout = gtk_print_context_create_pango_layout (context);
|
||||
|
||||
desc = pango_font_description_from_string ("sans 14");
|
||||
pango_layout_set_font_description (layout, desc);
|
||||
pango_font_description_free (desc);
|
||||
desc = pango2_font_description_from_string ("sans 14");
|
||||
pango2_layout_set_font_description (layout, desc);
|
||||
pango2_font_description_free (desc);
|
||||
|
||||
pango_layout_set_text (layout, data->resourcename, -1);
|
||||
pango_layout_get_pixel_size (layout, &text_width, &text_height);
|
||||
pango2_layout_set_text (layout, data->resourcename, -1);
|
||||
pango2_lines_get_extents (pango2_layout_get_lines (layout), NULL, &ext);
|
||||
pango2_extents_to_pixels (&ext, NULL);
|
||||
|
||||
if (text_width > width)
|
||||
if (ext.width > width)
|
||||
{
|
||||
pango_layout_set_width (layout, width);
|
||||
pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_START);
|
||||
pango_layout_get_pixel_size (layout, &text_width, &text_height);
|
||||
pango2_layout_set_width (layout, width);
|
||||
pango2_layout_set_ellipsize (layout, PANGO2_ELLIPSIZE_START);
|
||||
pango2_lines_get_extents (pango2_layout_get_lines (layout), NULL, &ext);
|
||||
pango2_extents_to_pixels (&ext, NULL);
|
||||
}
|
||||
|
||||
cairo_move_to (cr, (width - text_width) / 2, (HEADER_HEIGHT - text_height) / 2);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
cairo_move_to (cr, (width - ext.width) / 2, (HEADER_HEIGHT - ext.height) / 2);
|
||||
pango2_cairo_show_layout (cr, layout);
|
||||
|
||||
page_str = g_strdup_printf ("%d/%d", page_nr + 1, data->num_pages);
|
||||
pango_layout_set_text (layout, page_str, -1);
|
||||
pango2_layout_set_text (layout, page_str, -1);
|
||||
g_free (page_str);
|
||||
|
||||
pango_layout_set_width (layout, -1);
|
||||
pango_layout_get_pixel_size (layout, &text_width, &text_height);
|
||||
cairo_move_to (cr, width - text_width - 4, (HEADER_HEIGHT - text_height) / 2);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
pango2_layout_set_width (layout, -1);
|
||||
pango2_lines_get_extents (pango2_layout_get_lines (layout), NULL, &ext);
|
||||
pango2_extents_to_pixels (&ext, NULL);
|
||||
cairo_move_to (cr, width - ext.width - 4, (HEADER_HEIGHT - ext.height) / 2);
|
||||
pango2_cairo_show_layout (cr, layout);
|
||||
|
||||
g_object_unref (layout);
|
||||
|
||||
layout = gtk_print_context_create_pango_layout (context);
|
||||
|
||||
desc = pango_font_description_from_string ("monospace");
|
||||
pango_font_description_set_size (desc, data->font_size * PANGO_SCALE);
|
||||
pango_layout_set_font_description (layout, desc);
|
||||
pango_font_description_free (desc);
|
||||
desc = pango2_font_description_from_string ("monospace");
|
||||
pango2_font_description_set_size (desc, data->font_size * PANGO2_SCALE);
|
||||
pango2_layout_set_font_description (layout, desc);
|
||||
pango2_font_description_free (desc);
|
||||
|
||||
cairo_move_to (cr, 0, HEADER_HEIGHT + HEADER_GAP);
|
||||
line = page_nr * data->lines_per_page;
|
||||
for (i = 0; i < data->lines_per_page && line < data->num_lines; i++)
|
||||
{
|
||||
pango_layout_set_text (layout, data->lines[line], -1);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
pango2_layout_set_text (layout, data->lines[line], -1);
|
||||
pango2_cairo_show_layout (cr, layout);
|
||||
cairo_rel_move_to (cr, 0, data->font_size);
|
||||
line++;
|
||||
}
|
||||
|
||||
239
demos/gtk-demo/read_more.c
Normal file
239
demos/gtk-demo/read_more.c
Normal file
@@ -0,0 +1,239 @@
|
||||
/* Read More
|
||||
* #Keywords: GtkInscription
|
||||
*
|
||||
* A simple implementation of a widget that can either
|
||||
* display a lot of text or just the first few lines with a
|
||||
* "Read More" button.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define READ_TYPE_MORE (read_more_get_type ())
|
||||
G_DECLARE_FINAL_TYPE(ReadMore, read_more, READ, MORE, GtkWidget)
|
||||
|
||||
struct _ReadMore {
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GtkWidget *label;
|
||||
GtkWidget *inscription;
|
||||
GtkWidget *box;
|
||||
gboolean show_more;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ReadMore, read_more, GTK_TYPE_WIDGET)
|
||||
|
||||
static GtkSizeRequestMode
|
||||
read_more_get_request_mode (GtkWidget *widget)
|
||||
{
|
||||
return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
|
||||
}
|
||||
|
||||
static void
|
||||
read_more_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
ReadMore *self = READ_MORE (widget);
|
||||
int label_min, label_nat, label_min_baseline, label_nat_baseline;
|
||||
int box_min, box_nat, box_min_baseline, box_nat_baseline;
|
||||
int min_check;
|
||||
|
||||
if (self->show_more)
|
||||
min_check = G_MAXINT;
|
||||
else if (for_size >= 0)
|
||||
gtk_widget_measure (self->box, 1 - orientation, -1, &min_check, NULL, NULL, NULL);
|
||||
else
|
||||
min_check = -1;
|
||||
|
||||
if (min_check > for_size)
|
||||
{
|
||||
gtk_widget_measure (self->label,
|
||||
orientation,
|
||||
for_size,
|
||||
minimum, natural,
|
||||
minimum_baseline, natural_baseline);
|
||||
return;
|
||||
}
|
||||
|
||||
else if (for_size >= 0)
|
||||
gtk_widget_measure (self->label, 1 - orientation, -1, &min_check, NULL, NULL, NULL);
|
||||
else
|
||||
min_check = -1;
|
||||
|
||||
if (min_check > for_size)
|
||||
{
|
||||
gtk_widget_measure (self->box,
|
||||
orientation,
|
||||
for_size,
|
||||
minimum, natural,
|
||||
minimum_baseline, natural_baseline);
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_widget_measure (self->label,
|
||||
orientation,
|
||||
for_size,
|
||||
&label_min, &label_nat,
|
||||
&label_min_baseline, &label_nat_baseline);
|
||||
gtk_widget_measure (self->box,
|
||||
orientation,
|
||||
for_size,
|
||||
&box_min, &box_nat,
|
||||
&box_min_baseline, &box_nat_baseline);
|
||||
|
||||
*minimum = MIN (label_min, box_min);
|
||||
*natural = MIN (label_nat, box_nat);
|
||||
|
||||
/* FIXME: Figure out baselines! */
|
||||
}
|
||||
|
||||
static void
|
||||
read_more_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
ReadMore *self = READ_MORE (widget);
|
||||
gboolean show_more;
|
||||
|
||||
if (self->show_more)
|
||||
{
|
||||
show_more = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
int needed;
|
||||
|
||||
/* check to see if we have enough space to show all text */
|
||||
gtk_widget_measure (self->label,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
width,
|
||||
&needed, NULL, NULL, NULL);
|
||||
|
||||
show_more = needed <= height;
|
||||
}
|
||||
|
||||
gtk_widget_set_child_visible (self->label, show_more);
|
||||
gtk_widget_set_child_visible (self->box, !show_more);
|
||||
|
||||
if (show_more)
|
||||
gtk_widget_size_allocate (self->label, &(GtkAllocation) { 0, 0, width, height }, baseline);
|
||||
else
|
||||
gtk_widget_size_allocate (self->box, &(GtkAllocation) { 0, 0, width, height }, baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
read_more_dispose (GObject *object)
|
||||
{
|
||||
ReadMore *self = READ_MORE (object);
|
||||
|
||||
g_clear_pointer (&self->label, gtk_widget_unparent);
|
||||
g_clear_pointer (&self->box, gtk_widget_unparent);
|
||||
|
||||
G_OBJECT_CLASS (read_more_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
read_more_class_init (ReadMoreClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
widget_class->get_request_mode = read_more_get_request_mode;
|
||||
widget_class->measure = read_more_measure;
|
||||
widget_class->size_allocate = read_more_allocate;
|
||||
|
||||
object_class->dispose = read_more_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
read_more_clicked (GtkButton *button,
|
||||
ReadMore *self)
|
||||
{
|
||||
self->show_more = TRUE;
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
read_more_init (ReadMore *self)
|
||||
{
|
||||
GtkWidget *button;
|
||||
|
||||
self->label = gtk_label_new (NULL);
|
||||
gtk_label_set_xalign (GTK_LABEL (self->label), 0.0);
|
||||
gtk_label_set_yalign (GTK_LABEL (self->label), 0.0);
|
||||
gtk_label_set_wrap (GTK_LABEL (self->label), TRUE);
|
||||
gtk_label_set_width_chars (GTK_LABEL (self->label), 3);
|
||||
gtk_label_set_max_width_chars (GTK_LABEL (self->label), 30);
|
||||
gtk_widget_set_parent (self->label, GTK_WIDGET (self));
|
||||
|
||||
self->box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_widget_set_vexpand (self->box, FALSE);
|
||||
gtk_widget_set_parent (self->box, GTK_WIDGET (self));
|
||||
|
||||
self->inscription = gtk_inscription_new (NULL);
|
||||
gtk_inscription_set_xalign (GTK_INSCRIPTION (self->inscription), 0.0);
|
||||
gtk_inscription_set_yalign (GTK_INSCRIPTION (self->inscription), 0.0);
|
||||
gtk_inscription_set_min_lines (GTK_INSCRIPTION (self->inscription), 3);
|
||||
gtk_inscription_set_nat_chars (GTK_INSCRIPTION (self->inscription), 30);
|
||||
gtk_widget_set_vexpand (self->inscription, TRUE);
|
||||
gtk_box_append (GTK_BOX (self->box), self->inscription);
|
||||
|
||||
button = gtk_button_new_with_label ("Read More");
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (read_more_clicked), self);
|
||||
gtk_box_append (GTK_BOX (self->box), button);
|
||||
}
|
||||
|
||||
static void
|
||||
read_more_set_text (ReadMore *self,
|
||||
const char *text)
|
||||
{
|
||||
gtk_label_set_label (GTK_LABEL (self->label), text);
|
||||
gtk_inscription_set_text (GTK_INSCRIPTION (self->inscription), text);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
read_more_new (const char *text)
|
||||
{
|
||||
ReadMore *self = g_object_new (READ_TYPE_MORE, NULL);
|
||||
|
||||
read_more_set_text (self, text);
|
||||
|
||||
return GTK_WIDGET (self);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_read_more (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *readmore;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Read More");
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
readmore = read_more_new (
|
||||
"I'd just like to interject for a moment. What you're referring to as Linux, is in fact, GNU/Linux, or as I've recently taken to calling it, GNU plus Linux. Linux is not an operating system unto itself, but rather another free component of a fully functioning GNU system made useful by the GNU corelibs, shell utilities and vital system components comprising a full OS as defined by POSIX.\n"
|
||||
"\n"
|
||||
"Many computer users run a modified version of the GNU system every day, without realizing it. Through a peculiar turn of events, the version of GNU which is widely used today is often called \"Linux\", and many of its users are not aware that it is basically the GNU system, developed by the GNU Project.\n"
|
||||
"\n"
|
||||
"There really is a Linux, and these people are using it, but it is just a part of the system they use. Linux is the kernel: the program in the system that allocates the machine's resources to the other programs that you run. The kernel is an essential part of an operating system, but useless by itself; it can only function in the context of a complete operating system. Linux is normally used in combination with the GNU operating system: the whole system is basically GNU with Linux added, or GNU/Linux. All the so-called \"Linux\" distributions are really distributions of GNU/Linux.");
|
||||
gtk_window_set_child (GTK_WINDOW (window), readmore);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
/* Pango/Rotated Text
|
||||
/* Pango2/Rotated Text
|
||||
*
|
||||
* This demo shows how to use PangoCairo to draw rotated and transformed
|
||||
* This demo shows how to use Pango2Cairo to draw rotated and transformed
|
||||
* text. The right pane shows a rotated GtkLabel widget.
|
||||
*
|
||||
* In both cases, a custom PangoCairo shape renderer is installed to draw
|
||||
* In both cases, a custom Pango2Cairo shape renderer is installed to draw
|
||||
* a red heart using cairo drawing operations instead of the Unicode heart
|
||||
* character.
|
||||
*/
|
||||
@@ -14,75 +14,118 @@
|
||||
#define HEART "♥"
|
||||
const char text[] = "I ♥ GTK";
|
||||
|
||||
static void
|
||||
fancy_shape_renderer (cairo_t *cr,
|
||||
PangoAttrShape *attr,
|
||||
gboolean do_path,
|
||||
gpointer data)
|
||||
static gboolean
|
||||
glyph_cb (Pango2UserFace *face,
|
||||
hb_codepoint_t unicode,
|
||||
hb_codepoint_t *glyph,
|
||||
gpointer data)
|
||||
{
|
||||
double x, y;
|
||||
cairo_get_current_point (cr, &x, &y);
|
||||
cairo_translate (cr, x, y);
|
||||
|
||||
cairo_scale (cr,
|
||||
(double) attr->ink_rect.width / PANGO_SCALE,
|
||||
(double) attr->ink_rect.height / PANGO_SCALE);
|
||||
|
||||
if (GPOINTER_TO_UINT (attr->data) == 0x2665) /* U+2665 BLACK HEART SUIT */
|
||||
if (unicode == 0x2665)
|
||||
{
|
||||
*glyph = 0x2665;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
glyph_info_cb (Pango2UserFace *face,
|
||||
int size,
|
||||
hb_codepoint_t glyph,
|
||||
hb_glyph_extents_t *extents,
|
||||
hb_position_t *h_advance,
|
||||
hb_position_t *v_advance,
|
||||
gboolean *is_color,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (glyph == 0x2665)
|
||||
{
|
||||
extents->x_bearing = 0;
|
||||
extents->y_bearing = size;
|
||||
extents->width = size;
|
||||
extents->height = - size;
|
||||
|
||||
*h_advance = size;
|
||||
*v_advance = size;
|
||||
*is_color = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
font_info_cb (Pango2UserFace *face,
|
||||
int size,
|
||||
hb_font_extents_t *extents,
|
||||
gpointer user_data)
|
||||
{
|
||||
extents->ascender = size;
|
||||
extents->descender = 0;
|
||||
extents->line_gap = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
render_cb (Pango2UserFace *face,
|
||||
int size,
|
||||
hb_codepoint_t glyph,
|
||||
gpointer user_data,
|
||||
const char *backend_id,
|
||||
gpointer backend_data)
|
||||
{
|
||||
cairo_t *cr;
|
||||
|
||||
if (strcmp (backend_id, "cairo") != 0)
|
||||
{
|
||||
g_warning ("Unsupported Pango2Renderer backend %s", backend_id);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cr = backend_data;
|
||||
|
||||
if (glyph == 0x2665)
|
||||
{
|
||||
cairo_set_source_rgb (cr, 1., 0., 0.);
|
||||
|
||||
cairo_move_to (cr, .5, .0);
|
||||
cairo_line_to (cr, .9, -.4);
|
||||
cairo_curve_to (cr, 1.1, -.8, .5, -.9, .5, -.5);
|
||||
cairo_curve_to (cr, .5, -.9, -.1, -.8, .1, -.4);
|
||||
cairo_close_path (cr);
|
||||
cairo_fill (cr);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!do_path)
|
||||
{
|
||||
cairo_set_source_rgb (cr, 1., 0., 0.);
|
||||
cairo_fill (cr);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static PangoAttrList *
|
||||
create_fancy_attr_list_for_layout (PangoLayout *layout)
|
||||
static void
|
||||
setup_fontmap (void)
|
||||
{
|
||||
PangoAttrList *attrs;
|
||||
PangoFontMetrics *metrics;
|
||||
int ascent;
|
||||
PangoRectangle ink_rect, logical_rect;
|
||||
const char *p;
|
||||
Pango2FontMap *fontmap = pango2_font_map_get_default ();
|
||||
Pango2FontDescription *desc;
|
||||
Pango2UserFace *face;
|
||||
|
||||
/* Get font metrics and prepare fancy shape size */
|
||||
metrics = pango_context_get_metrics (pango_layout_get_context (layout),
|
||||
pango_layout_get_font_description (layout),
|
||||
NULL);
|
||||
ascent = pango_font_metrics_get_ascent (metrics);
|
||||
logical_rect.x = 0;
|
||||
logical_rect.width = ascent;
|
||||
logical_rect.y = -ascent;
|
||||
logical_rect.height = ascent;
|
||||
ink_rect = logical_rect;
|
||||
pango_font_metrics_unref (metrics);
|
||||
desc = pango2_font_description_new ();
|
||||
pango2_font_description_set_family (desc, "Bullets");
|
||||
|
||||
/* Set fancy shape attributes for all hearts */
|
||||
attrs = pango_attr_list_new ();
|
||||
for (p = text; (p = strstr (p, HEART)); p += strlen (HEART))
|
||||
{
|
||||
PangoAttribute *attr;
|
||||
/* Create our fancy user font, "Bullets Black" */
|
||||
face = pango2_user_face_new (font_info_cb,
|
||||
glyph_cb,
|
||||
glyph_info_cb,
|
||||
NULL,
|
||||
render_cb,
|
||||
NULL, NULL, "Black", desc);
|
||||
|
||||
attr = pango_attr_shape_new_with_data (&ink_rect,
|
||||
&logical_rect,
|
||||
GUINT_TO_POINTER (g_utf8_get_char (p)),
|
||||
NULL, NULL);
|
||||
/* And add it to the default fontmap */
|
||||
pango2_font_map_add_face (fontmap, PANGO2_FONT_FACE (face));
|
||||
|
||||
attr->start_index = p - text;
|
||||
attr->end_index = attr->start_index + strlen (HEART);
|
||||
|
||||
pango_attr_list_insert (attrs, attr);
|
||||
}
|
||||
|
||||
return attrs;
|
||||
pango2_font_description_free (desc);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -94,16 +137,12 @@ rotated_text_draw (GtkDrawingArea *da,
|
||||
{
|
||||
#define RADIUS 150
|
||||
#define N_WORDS 5
|
||||
#define FONT "Serif 18"
|
||||
|
||||
PangoContext *context;
|
||||
PangoLayout *layout;
|
||||
PangoFontDescription *desc;
|
||||
#define FONT "Bullets 18"
|
||||
|
||||
Pango2Context *context;
|
||||
Pango2Layout *layout;
|
||||
Pango2FontDescription *desc;
|
||||
cairo_pattern_t *pattern;
|
||||
|
||||
PangoAttrList *attrs;
|
||||
|
||||
double device_radius;
|
||||
int i;
|
||||
|
||||
@@ -123,40 +162,34 @@ rotated_text_draw (GtkDrawingArea *da,
|
||||
cairo_pattern_add_color_stop_rgb (pattern, 1., .0, .0, .5);
|
||||
cairo_set_source (cr, pattern);
|
||||
|
||||
/* Create a PangoContext and set up our shape renderer */
|
||||
/* Create a Pango2Context and set up our shape renderer */
|
||||
context = gtk_widget_create_pango_context (GTK_WIDGET (da));
|
||||
pango_cairo_context_set_shape_renderer (context,
|
||||
fancy_shape_renderer,
|
||||
NULL, NULL);
|
||||
|
||||
/* Create a PangoLayout, set the text, font, and attributes */
|
||||
layout = pango_layout_new (context);
|
||||
pango_layout_set_text (layout, text, -1);
|
||||
desc = pango_font_description_from_string (FONT);
|
||||
pango_layout_set_font_description (layout, desc);
|
||||
|
||||
attrs = create_fancy_attr_list_for_layout (layout);
|
||||
pango_layout_set_attributes (layout, attrs);
|
||||
pango_attr_list_unref (attrs);
|
||||
/* Create a Pango2Layout, set the text, font, and attributes */
|
||||
layout = pango2_layout_new (context);
|
||||
pango2_layout_set_text (layout, text, -1);
|
||||
desc = pango2_font_description_from_string (FONT);
|
||||
pango2_layout_set_font_description (layout, desc);
|
||||
|
||||
/* Draw the layout N_WORDS times in a circle */
|
||||
for (i = 0; i < N_WORDS; i++)
|
||||
{
|
||||
int layout_width, layout_height;
|
||||
Pango2Rectangle ext;
|
||||
|
||||
/* Inform Pango to re-layout the text with the new transformation matrix */
|
||||
pango_cairo_update_layout (cr, layout);
|
||||
/* Inform Pango2 to re-layout the text with the new transformation matrix */
|
||||
pango2_cairo_update_layout (cr, layout);
|
||||
|
||||
pango_layout_get_pixel_size (layout, &layout_width, &layout_height);
|
||||
cairo_move_to (cr, - layout_width / 2, - RADIUS * .9);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
pango2_lines_get_extents (pango2_layout_get_lines (layout), NULL, &ext);
|
||||
pango2_extents_to_pixels (&ext, NULL);
|
||||
cairo_move_to (cr, - ext.width / 2, - RADIUS * .9);
|
||||
pango2_cairo_show_layout (cr, layout);
|
||||
|
||||
/* Rotate for the next turn */
|
||||
cairo_rotate (cr, G_PI*2 / N_WORDS);
|
||||
}
|
||||
|
||||
/* free the objects we created */
|
||||
pango_font_description_free (desc);
|
||||
pango2_font_description_free (desc);
|
||||
g_object_unref (layout);
|
||||
g_object_unref (context);
|
||||
cairo_pattern_destroy (pattern);
|
||||
@@ -172,8 +205,10 @@ do_rotated_text (GtkWidget *do_widget)
|
||||
GtkWidget *box;
|
||||
GtkWidget *drawing_area;
|
||||
GtkWidget *label;
|
||||
PangoLayout *layout;
|
||||
PangoAttrList *attrs;
|
||||
Pango2Attribute *attr;
|
||||
Pango2AttrList *attrs;
|
||||
|
||||
setup_fontmap ();
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
@@ -197,16 +232,12 @@ do_rotated_text (GtkWidget *do_widget)
|
||||
|
||||
/* And a label */
|
||||
label = gtk_label_new (text);
|
||||
gtk_box_append (GTK_BOX (box), label);
|
||||
|
||||
/* Set up fancy stuff on the label */
|
||||
layout = gtk_label_get_layout (GTK_LABEL (label));
|
||||
pango_cairo_context_set_shape_renderer (pango_layout_get_context (layout),
|
||||
fancy_shape_renderer,
|
||||
NULL, NULL);
|
||||
attrs = create_fancy_attr_list_for_layout (layout);
|
||||
attrs = pango2_attr_list_new ();
|
||||
attr = pango2_attr_font_desc_new (pango2_font_description_from_string (FONT));
|
||||
pango2_attr_list_insert (attrs, attr);
|
||||
gtk_label_set_attributes (GTK_LABEL (label), attrs);
|
||||
pango_attr_list_unref (attrs);
|
||||
pango2_attr_list_unref (attrs);
|
||||
gtk_box_append (GTK_BOX (box), label);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -1,260 +0,0 @@
|
||||
#include "simplelabel.h"
|
||||
|
||||
struct _SimpleLabel
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
PangoLayout *layout;
|
||||
int min_chars;
|
||||
int nat_chars;
|
||||
|
||||
int min_width;
|
||||
int nat_width;
|
||||
int height;
|
||||
};
|
||||
|
||||
struct _SimpleLabelClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_TEXT = 1,
|
||||
PROP_MIN_CHARS,
|
||||
PROP_NAT_CHARS,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
G_DEFINE_TYPE (SimpleLabel, simple_label, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
simple_label_init (SimpleLabel *self)
|
||||
{
|
||||
self->layout = gtk_widget_create_pango_layout (GTK_WIDGET (self), "");
|
||||
pango_layout_set_ellipsize (self->layout, PANGO_ELLIPSIZE_NONE);
|
||||
pango_layout_set_wrap (self->layout, PANGO_WRAP_WORD);
|
||||
pango_layout_set_width (self->layout, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
simple_label_dispose (GObject *object)
|
||||
{
|
||||
SimpleLabel *self = SIMPLE_LABEL (object);
|
||||
|
||||
g_clear_object (&self->layout);
|
||||
|
||||
G_OBJECT_CLASS (simple_label_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
simple_label_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
SimpleLabel *self = SIMPLE_LABEL (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TEXT:
|
||||
simple_label_set_text (self, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_MIN_CHARS:
|
||||
simple_label_set_min_chars (self, g_value_get_int (value));
|
||||
break;
|
||||
|
||||
case PROP_NAT_CHARS:
|
||||
simple_label_set_nat_chars (self, g_value_get_int (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
simple_label_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
SimpleLabel *self = SIMPLE_LABEL (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TEXT:
|
||||
g_value_set_string (value, pango_layout_get_text (self->layout));
|
||||
break;
|
||||
|
||||
case PROP_MIN_CHARS:
|
||||
g_value_set_int (value, self->min_chars);
|
||||
break;
|
||||
|
||||
case PROP_NAT_CHARS:
|
||||
g_value_set_int (value, self->nat_chars);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
simple_label_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
SimpleLabel *self = SIMPLE_LABEL (widget);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_VERTICAL)
|
||||
{
|
||||
*minimum = *natural = self->height;
|
||||
}
|
||||
else
|
||||
{
|
||||
*minimum = self->min_width;
|
||||
*natural = self->nat_width;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
simple_label_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
SimpleLabel *self = SIMPLE_LABEL (widget);
|
||||
|
||||
pango_layout_set_width (self->layout, width * PANGO_SCALE);
|
||||
}
|
||||
|
||||
static void
|
||||
simple_label_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
SimpleLabel *self = SIMPLE_LABEL (widget);
|
||||
GtkStyleContext *context;
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
|
||||
gtk_snapshot_render_layout (snapshot, context, 0, 0, self->layout);
|
||||
}
|
||||
|
||||
static void
|
||||
simple_label_class_init (SimpleLabelClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
object_class->dispose = simple_label_dispose;
|
||||
object_class->set_property = simple_label_set_property;
|
||||
object_class->get_property = simple_label_get_property;
|
||||
|
||||
widget_class->measure = simple_label_measure;
|
||||
widget_class->size_allocate = simple_label_size_allocate;
|
||||
widget_class->snapshot = simple_label_snapshot;
|
||||
|
||||
properties[PROP_TEXT] =
|
||||
g_param_spec_string ("text", "Text", "Text",
|
||||
NULL,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_MIN_CHARS] =
|
||||
g_param_spec_int ("min-chars", "Minimum Characters", "Minimum Characters",
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_NAT_CHARS] =
|
||||
g_param_spec_int ("nat-chars", "Natural Characters", "Natural Characters",
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
simple_label_new (void)
|
||||
{
|
||||
return g_object_new (SIMPLE_TYPE_LABEL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
simple_label_set_text (SimpleLabel *self,
|
||||
const char *text)
|
||||
{
|
||||
if (strcmp (text, pango_layout_get_text (self->layout)) == 0)
|
||||
return;
|
||||
|
||||
pango_layout_set_text (self->layout, text, -1);
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TEXT]);
|
||||
}
|
||||
|
||||
static void
|
||||
recalculate (SimpleLabel *self)
|
||||
{
|
||||
PangoContext *context;
|
||||
PangoFontMetrics *metrics;
|
||||
int char_width;
|
||||
int digit_width;
|
||||
int width;
|
||||
int ascent;
|
||||
int descent;
|
||||
|
||||
context = gtk_widget_get_pango_context (GTK_WIDGET (self));
|
||||
metrics = pango_context_get_metrics (context,
|
||||
pango_context_get_font_description (context),
|
||||
pango_context_get_language (context));
|
||||
char_width = pango_font_metrics_get_approximate_char_width (metrics);
|
||||
digit_width = pango_font_metrics_get_approximate_digit_width (metrics);
|
||||
ascent = pango_font_metrics_get_ascent (metrics);
|
||||
descent = pango_font_metrics_get_descent (metrics);
|
||||
pango_font_metrics_unref (metrics);
|
||||
|
||||
width = MAX (char_width, digit_width);
|
||||
|
||||
self->min_width = (width * self->min_chars) / PANGO_SCALE;
|
||||
self->nat_width = (width * self->nat_chars) / PANGO_SCALE;
|
||||
self->height = (ascent + descent) / PANGO_SCALE;
|
||||
}
|
||||
|
||||
void
|
||||
simple_label_set_min_chars (SimpleLabel *self,
|
||||
int min_chars)
|
||||
{
|
||||
if (self->min_chars == min_chars)
|
||||
return;
|
||||
|
||||
self->min_chars = min_chars;
|
||||
|
||||
recalculate (self);
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MIN_CHARS]);
|
||||
}
|
||||
|
||||
void
|
||||
simple_label_set_nat_chars (SimpleLabel *self,
|
||||
int nat_chars)
|
||||
{
|
||||
if (self->nat_chars == nat_chars)
|
||||
return;
|
||||
|
||||
self->nat_chars = nat_chars;
|
||||
|
||||
recalculate (self);
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_NAT_CHARS]);
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define SIMPLE_TYPE_LABEL (simple_label_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (SimpleLabel, simple_label, SIMPLE, LABEL, GtkWidget)
|
||||
|
||||
GtkWidget * simple_label_new (void);
|
||||
|
||||
void simple_label_set_text (SimpleLabel *self,
|
||||
const char *text);
|
||||
void simple_label_set_min_chars (SimpleLabel *self,
|
||||
int min_chars);
|
||||
void simple_label_set_nat_chars (SimpleLabel *self,
|
||||
int nat_chars);
|
||||
@@ -21,7 +21,7 @@ do_tabs (GtkWidget *do_widget)
|
||||
GtkWidget *view;
|
||||
GtkWidget *sw;
|
||||
GtkTextBuffer *buffer;
|
||||
PangoTabArray *tabs;
|
||||
Pango2TabArray *tabs;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Tabs");
|
||||
@@ -38,13 +38,13 @@ do_tabs (GtkWidget *do_widget)
|
||||
gtk_text_view_set_left_margin (GTK_TEXT_VIEW (view), 20);
|
||||
gtk_text_view_set_right_margin (GTK_TEXT_VIEW (view), 20);
|
||||
|
||||
tabs = pango_tab_array_new (3, TRUE);
|
||||
pango_tab_array_set_tab (tabs, 0, PANGO_TAB_LEFT, 0);
|
||||
pango_tab_array_set_tab (tabs, 1, PANGO_TAB_DECIMAL, 150);
|
||||
pango_tab_array_set_decimal_point (tabs, 1, '.');
|
||||
pango_tab_array_set_tab (tabs, 2, PANGO_TAB_RIGHT, 290);
|
||||
tabs = pango2_tab_array_new (3, TRUE);
|
||||
pango2_tab_array_set_tab (tabs, 0, PANGO2_TAB_LEFT, 0);
|
||||
pango2_tab_array_set_tab (tabs, 1, PANGO2_TAB_DECIMAL, 150);
|
||||
pango2_tab_array_set_decimal_point (tabs, 1, '.');
|
||||
pango2_tab_array_set_tab (tabs, 2, PANGO2_TAB_RIGHT, 290);
|
||||
gtk_text_view_set_tabs (GTK_TEXT_VIEW (view), tabs);
|
||||
pango_tab_array_free (tabs);
|
||||
pango2_tab_array_free (tabs);
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
gtk_text_buffer_set_text (buffer, "one\t2.0\tthree\nfour\t5.555\tsix\nseven\t88.88\tnine", -1);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Pango/Text Mask
|
||||
*
|
||||
* This demo shows how to use PangoCairo to draw text with more than
|
||||
* This demo shows how to use Pango to draw text with more than
|
||||
* just a single color.
|
||||
*/
|
||||
|
||||
@@ -15,18 +15,18 @@ draw_text (GtkDrawingArea *da,
|
||||
gpointer data)
|
||||
{
|
||||
cairo_pattern_t *pattern;
|
||||
PangoLayout *layout;
|
||||
PangoFontDescription *desc;
|
||||
Pango2Layout *layout;
|
||||
Pango2FontDescription *desc;
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
layout = gtk_widget_create_pango_layout (GTK_WIDGET (da), "Pango power!\nPango power!\nPango power!");
|
||||
desc = pango_font_description_from_string ("sans bold 34");
|
||||
pango_layout_set_font_description (layout, desc);
|
||||
pango_font_description_free (desc);
|
||||
desc = pango2_font_description_from_string ("sans bold 34");
|
||||
pango2_layout_set_font_description (layout, desc);
|
||||
pango2_font_description_free (desc);
|
||||
|
||||
cairo_move_to (cr, 30, 20);
|
||||
pango_cairo_layout_path (cr, layout);
|
||||
pango2_cairo_layout_path (cr, layout);
|
||||
g_object_unref (layout);
|
||||
|
||||
pattern = cairo_pattern_create_linear (0.0, 0.0, width, height);
|
||||
|
||||
@@ -36,25 +36,25 @@ create_tags (GtkTextBuffer *buffer)
|
||||
*/
|
||||
|
||||
gtk_text_buffer_create_tag (buffer, "heading",
|
||||
"weight", PANGO_WEIGHT_BOLD,
|
||||
"size", 15 * PANGO_SCALE,
|
||||
"weight", PANGO2_WEIGHT_BOLD,
|
||||
"size", 15 * PANGO2_SCALE,
|
||||
NULL);
|
||||
|
||||
gtk_text_buffer_create_tag (buffer, "italic",
|
||||
"style", PANGO_STYLE_ITALIC, NULL);
|
||||
"style", PANGO2_STYLE_ITALIC, NULL);
|
||||
|
||||
gtk_text_buffer_create_tag (buffer, "bold",
|
||||
"weight", PANGO_WEIGHT_BOLD, NULL);
|
||||
"weight", PANGO2_WEIGHT_BOLD, NULL);
|
||||
|
||||
gtk_text_buffer_create_tag (buffer, "big",
|
||||
/* points times the PANGO_SCALE factor */
|
||||
"size", 20 * PANGO_SCALE, NULL);
|
||||
/* points times the PANGO2_SCALE factor */
|
||||
"size", 20 * PANGO2_SCALE, NULL);
|
||||
|
||||
gtk_text_buffer_create_tag (buffer, "xx-small",
|
||||
"scale", PANGO_SCALE_XX_SMALL, NULL);
|
||||
"scale", PANGO2_SCALE_XX_SMALL, NULL);
|
||||
|
||||
gtk_text_buffer_create_tag (buffer, "x-large",
|
||||
"scale", PANGO_SCALE_X_LARGE, NULL);
|
||||
"scale", PANGO2_SCALE_X_LARGE, NULL);
|
||||
|
||||
gtk_text_buffer_create_tag (buffer, "monospace",
|
||||
"family", "monospace", NULL);
|
||||
@@ -100,19 +100,19 @@ create_tags (GtkTextBuffer *buffer)
|
||||
"strikethrough", TRUE, NULL);
|
||||
|
||||
gtk_text_buffer_create_tag (buffer, "underline",
|
||||
"underline", PANGO_UNDERLINE_SINGLE, NULL);
|
||||
"underline", PANGO2_LINE_STYLE_SOLID, NULL);
|
||||
|
||||
gtk_text_buffer_create_tag (buffer, "double_underline",
|
||||
"underline", PANGO_UNDERLINE_DOUBLE, NULL);
|
||||
"underline", PANGO2_LINE_STYLE_DOUBLE, NULL);
|
||||
|
||||
gtk_text_buffer_create_tag (buffer, "superscript",
|
||||
"rise", 10 * PANGO_SCALE, /* 10 pixels */
|
||||
"size", 8 * PANGO_SCALE, /* 8 points */
|
||||
"rise", 10 * PANGO2_SCALE, /* 10 pixels */
|
||||
"size", 8 * PANGO2_SCALE, /* 8 points */
|
||||
NULL);
|
||||
|
||||
gtk_text_buffer_create_tag (buffer, "subscript",
|
||||
"rise", -10 * PANGO_SCALE, /* 10 pixels */
|
||||
"size", 8 * PANGO_SCALE, /* 8 points */
|
||||
"rise", -10 * PANGO2_SCALE, /* 10 pixels */
|
||||
"size", 8 * PANGO2_SCALE, /* 8 points */
|
||||
NULL);
|
||||
|
||||
gtk_text_buffer_create_tag (buffer, "rtl_quote",
|
||||
@@ -137,7 +137,7 @@ insert_text (GtkTextView *view)
|
||||
|
||||
icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (widget));
|
||||
icon = gtk_icon_theme_lookup_icon (icon_theme,
|
||||
"face-cool",
|
||||
"drive-harddisk",
|
||||
NULL,
|
||||
32, 1,
|
||||
gtk_widget_get_direction (widget),
|
||||
@@ -239,8 +239,6 @@ insert_text (GtkTextView *view)
|
||||
|
||||
gtk_text_buffer_insert (buffer, &iter, "The buffer can have images in it: ", -1);
|
||||
gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE (icon));
|
||||
gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE (icon));
|
||||
|
||||
gtk_text_buffer_insert_paintable (buffer, &iter, nuclear);
|
||||
|
||||
gtk_text_buffer_insert (buffer, &iter, " for example.\n\n", -1);
|
||||
@@ -441,11 +439,12 @@ attach_widgets (GtkTextView *text_view)
|
||||
{
|
||||
widget = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, NULL);
|
||||
gtk_range_set_range (GTK_RANGE (widget), 0, 100);
|
||||
gtk_widget_set_size_request (widget, 70, -1);
|
||||
gtk_widget_set_size_request (widget, 100, -1);
|
||||
}
|
||||
else if (i == 3)
|
||||
{
|
||||
widget = gtk_entry_new ();
|
||||
gtk_editable_set_width_chars (GTK_EDITABLE (widget), 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -70,8 +70,8 @@ about_activated (GSimpleAction *action,
|
||||
glib_major_version,
|
||||
glib_minor_version,
|
||||
glib_micro_version);
|
||||
g_string_append_printf (s, "\tPango\t%s\n",
|
||||
pango_version_string ());
|
||||
g_string_append_printf (s, "\tPango2\t%s\n",
|
||||
pango2_version_string ());
|
||||
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
|
||||
@@ -22,3 +22,4 @@ subdir('icon-browser')
|
||||
subdir('node-editor')
|
||||
subdir('widget-factory')
|
||||
subdir('print-editor')
|
||||
subdir('font-explorer')
|
||||
|
||||
@@ -77,8 +77,8 @@ activate_about (GSimpleAction *action,
|
||||
glib_major_version,
|
||||
glib_minor_version,
|
||||
glib_micro_version);
|
||||
g_string_append_printf (s, "\tPango\t%s\n",
|
||||
pango_version_string ());
|
||||
g_string_append_printf (s, "\tPango2\t%s\n",
|
||||
pango2_version_string ());
|
||||
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
|
||||
@@ -57,6 +57,7 @@ struct _NodeEditorWindow
|
||||
GtkWidget *testcase_cairo_checkbutton;
|
||||
GtkWidget *testcase_name_entry;
|
||||
GtkWidget *testcase_save_button;
|
||||
GtkWidget *scale_scale;
|
||||
|
||||
GtkWidget *renderer_listbox;
|
||||
GListStore *renderers;
|
||||
@@ -171,6 +172,7 @@ text_changed (GtkTextBuffer *buffer,
|
||||
GBytes *bytes;
|
||||
GtkTextIter iter;
|
||||
GtkTextIter start, end;
|
||||
float scale;
|
||||
|
||||
g_array_remove_range (self->errors, 0, self->errors->len);
|
||||
text = get_current_text (self->text_buffer);
|
||||
@@ -181,6 +183,17 @@ text_changed (GtkTextBuffer *buffer,
|
||||
|
||||
/* If this is too slow, go fix the parser performance */
|
||||
self->node = gsk_render_node_deserialize (bytes, deserialize_error_func, self);
|
||||
|
||||
scale = gtk_scale_button_get_value (GTK_SCALE_BUTTON (self->scale_scale));
|
||||
if (self->node && scale != 1.0)
|
||||
{
|
||||
GskRenderNode *node;
|
||||
|
||||
node = gsk_transform_node_new (self->node, gsk_transform_scale (NULL, scale, scale));
|
||||
gsk_render_node_unref (self->node);
|
||||
self->node = node;
|
||||
}
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
if (self->node)
|
||||
{
|
||||
@@ -277,6 +290,14 @@ text_changed (GtkTextBuffer *buffer,
|
||||
&start, &end);
|
||||
}
|
||||
|
||||
static void
|
||||
scale_changed (GObject *object,
|
||||
GParamSpec *pspec,
|
||||
NodeEditorWindow *self)
|
||||
{
|
||||
text_changed (self->text_buffer, self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
text_view_query_tooltip_cb (GtkWidget *widget,
|
||||
int x,
|
||||
@@ -344,13 +365,13 @@ static void
|
||||
load_error (NodeEditorWindow *self,
|
||||
const char *error_message)
|
||||
{
|
||||
PangoLayout *layout;
|
||||
Pango2Layout *layout;
|
||||
GtkSnapshot *snapshot;
|
||||
GskRenderNode *node;
|
||||
GBytes *bytes;
|
||||
|
||||
layout = gtk_widget_create_pango_layout (GTK_WIDGET (self), error_message);
|
||||
pango_layout_set_width (layout, 300 * PANGO_SCALE);
|
||||
pango2_layout_set_width (layout, 300 * PANGO2_SCALE);
|
||||
snapshot = gtk_snapshot_new ();
|
||||
gtk_snapshot_append_layout (snapshot, layout, &(GdkRGBA) { 0.7, 0.13, 0.13, 1.0 });
|
||||
node = gtk_snapshot_free_to_node (snapshot);
|
||||
@@ -962,6 +983,7 @@ node_editor_window_class_init (NodeEditorWindowClass *class)
|
||||
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, testcase_cairo_checkbutton);
|
||||
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, testcase_name_entry);
|
||||
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, testcase_save_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, scale_scale);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, text_view_query_tooltip_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, open_cb);
|
||||
@@ -1038,7 +1060,7 @@ node_editor_window_init (NodeEditorWindow *self)
|
||||
gtk_text_tag_table_add (self->tag_table,
|
||||
g_object_new (GTK_TYPE_TEXT_TAG,
|
||||
"name", "error",
|
||||
"underline", PANGO_UNDERLINE_ERROR,
|
||||
"underline", PANGO2_LINE_STYLE_DOTTED,
|
||||
NULL));
|
||||
gtk_text_tag_table_add (self->tag_table,
|
||||
g_object_new (GTK_TYPE_TEXT_TAG,
|
||||
@@ -1068,6 +1090,7 @@ node_editor_window_init (NodeEditorWindow *self)
|
||||
|
||||
self->text_buffer = gtk_text_buffer_new (self->tag_table);
|
||||
g_signal_connect (self->text_buffer, "changed", G_CALLBACK (text_changed), self);
|
||||
g_signal_connect (self->scale_scale, "notify::value", G_CALLBACK (scale_changed), self);
|
||||
gtk_text_view_set_buffer (GTK_TEXT_VIEW (self->text_view), self->text_buffer);
|
||||
|
||||
/* Default */
|
||||
|
||||
@@ -157,6 +157,23 @@
|
||||
<signal name="notify::active" handler="dark_mode_cb" swapped="0"/>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkScaleButton" id="scale_scale">
|
||||
<property name="focus-on-click">0</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment">
|
||||
<property name="lower">1</property>
|
||||
<property name="value">1</property>
|
||||
<property name="upper">10</property>
|
||||
<property name="step-increment">0.1</property>
|
||||
<property name="page-increment">0.5</property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="icons">zoom-in-symbolic</property>
|
||||
<property name="tooltip-text" translatable="yes">Scale the image</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <config.h>
|
||||
#include <math.h>
|
||||
#include <pango/pangocairo.h>
|
||||
#include <pango2/pangocairo.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
@@ -200,7 +200,7 @@ save_file (GFile *save_filename)
|
||||
|
||||
typedef struct {
|
||||
char *text;
|
||||
PangoLayout *layout;
|
||||
Pango2Layout *layout;
|
||||
GList *page_breaks;
|
||||
GtkWidget *font_button;
|
||||
char *font;
|
||||
@@ -211,39 +211,41 @@ begin_print (GtkPrintOperation *operation,
|
||||
GtkPrintContext *context,
|
||||
PrintData *print_data)
|
||||
{
|
||||
PangoFontDescription *desc;
|
||||
PangoLayoutLine *layout_line;
|
||||
Pango2FontDescription *desc;
|
||||
Pango2Lines *lines;
|
||||
Pango2Line *line;
|
||||
double width, height;
|
||||
double page_height;
|
||||
GList *page_breaks;
|
||||
int num_lines;
|
||||
int line;
|
||||
int i;
|
||||
|
||||
width = gtk_print_context_get_width (context);
|
||||
height = gtk_print_context_get_height (context);
|
||||
|
||||
print_data->layout = gtk_print_context_create_pango_layout (context);
|
||||
|
||||
desc = pango_font_description_from_string (print_data->font);
|
||||
pango_layout_set_font_description (print_data->layout, desc);
|
||||
pango_font_description_free (desc);
|
||||
desc = pango2_font_description_from_string (print_data->font);
|
||||
pango2_layout_set_font_description (print_data->layout, desc);
|
||||
pango2_font_description_free (desc);
|
||||
|
||||
pango_layout_set_width (print_data->layout, width * PANGO_SCALE);
|
||||
pango2_layout_set_width (print_data->layout, width * PANGO2_SCALE);
|
||||
|
||||
pango_layout_set_text (print_data->layout, print_data->text, -1);
|
||||
pango2_layout_set_text (print_data->layout, print_data->text, -1);
|
||||
|
||||
num_lines = pango_layout_get_line_count (print_data->layout);
|
||||
lines = pango2_layout_get_lines (print_data->layout);
|
||||
num_lines = pango2_lines_get_line_count (lines);
|
||||
|
||||
page_breaks = NULL;
|
||||
page_height = 0;
|
||||
|
||||
for (line = 0; line < num_lines; line++)
|
||||
for (i = 0; i < num_lines; i++)
|
||||
{
|
||||
PangoRectangle ink_rect, logical_rect;
|
||||
Pango2Rectangle logical_rect;
|
||||
double line_height;
|
||||
|
||||
layout_line = pango_layout_get_line (print_data->layout, line);
|
||||
pango_layout_line_get_extents (layout_line, &ink_rect, &logical_rect);
|
||||
line = pango2_lines_get_lines (lines)[i];
|
||||
pango2_line_get_extents (line, NULL, &logical_rect);
|
||||
|
||||
line_height = logical_rect.height / 1024.0;
|
||||
|
||||
@@ -271,7 +273,7 @@ draw_page (GtkPrintOperation *operation,
|
||||
cairo_t *cr;
|
||||
GList *pagebreak;
|
||||
int start, end, i;
|
||||
PangoLayoutIter *iter;
|
||||
Pango2LineIter *iter;
|
||||
double start_pos;
|
||||
|
||||
if (page_nr == 0)
|
||||
@@ -284,7 +286,7 @@ draw_page (GtkPrintOperation *operation,
|
||||
|
||||
pagebreak = g_list_nth (print_data->page_breaks, page_nr);
|
||||
if (pagebreak == NULL)
|
||||
end = pango_layout_get_line_count (print_data->layout);
|
||||
end = pango2_lines_get_line_count (pango2_layout_get_lines (print_data->layout));
|
||||
else
|
||||
end = GPOINTER_TO_INT (pagebreak->data);
|
||||
|
||||
@@ -294,33 +296,33 @@ draw_page (GtkPrintOperation *operation,
|
||||
|
||||
i = 0;
|
||||
start_pos = 0;
|
||||
iter = pango_layout_get_iter (print_data->layout);
|
||||
iter = pango2_layout_get_iter (print_data->layout);
|
||||
do
|
||||
{
|
||||
PangoRectangle logical_rect;
|
||||
PangoLayoutLine *line;
|
||||
int baseline;
|
||||
Pango2Rectangle logical_rect;
|
||||
Pango2Line *line;
|
||||
int baseline;
|
||||
|
||||
if (i >= start)
|
||||
{
|
||||
line = pango_layout_iter_get_line (iter);
|
||||
line = pango2_line_iter_get_line (iter);
|
||||
|
||||
pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
|
||||
baseline = pango_layout_iter_get_baseline (iter);
|
||||
pango2_line_iter_get_line_extents (iter, NULL, &logical_rect);
|
||||
baseline = pango2_line_iter_get_line_baseline (iter);
|
||||
|
||||
if (i == start)
|
||||
start_pos = logical_rect.y / 1024.0;
|
||||
|
||||
cairo_move_to (cr, logical_rect.x / 1024.0, baseline / 1024.0 - start_pos);
|
||||
|
||||
pango_cairo_show_layout_line (cr, line);
|
||||
pango2_cairo_show_line (cr, line);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
while (i < end &&
|
||||
pango_layout_iter_next_line (iter));
|
||||
pango2_line_iter_next_line (iter));
|
||||
|
||||
pango_layout_iter_free (iter);
|
||||
pango2_line_iter_free (iter);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -626,8 +628,8 @@ activate_about (GSimpleAction *action,
|
||||
glib_major_version,
|
||||
glib_minor_version,
|
||||
glib_micro_version);
|
||||
g_string_append_printf (sysinfo, "\tPango\t%s\n",
|
||||
pango_version_string ());
|
||||
g_string_append_printf (sysinfo, "\tPango2\t%s\n",
|
||||
pango2_version_string ());
|
||||
g_string_append_printf (sysinfo, "\tGTK \t%d.%d.%d\n",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
|
||||
@@ -296,8 +296,8 @@ activate_about (GSimpleAction *action,
|
||||
glib_major_version,
|
||||
glib_minor_version,
|
||||
glib_micro_version);
|
||||
g_string_append_printf (s, "\tPango\t%s\n",
|
||||
pango_version_string ());
|
||||
g_string_append_printf (s, "\tPango2\t%s\n",
|
||||
pango2_version_string ());
|
||||
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
@@ -2081,26 +2081,23 @@ activate (GApplication *app)
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
scope = gtk_builder_cscope_new ();
|
||||
gtk_builder_cscope_add_callback_symbols (GTK_BUILDER_CSCOPE (scope),
|
||||
"on_entry_icon_release", (GCallback)on_entry_icon_release,
|
||||
"on_scale_button_value_changed", (GCallback)on_scale_button_value_changed,
|
||||
"on_record_button_toggled", (GCallback)on_record_button_toggled,
|
||||
"on_page_combo_changed", (GCallback)on_page_combo_changed,
|
||||
"on_range_from_changed", (GCallback)on_range_from_changed,
|
||||
"on_range_to_changed", (GCallback)on_range_to_changed,
|
||||
"on_picture_drag_prepare", (GCallback)on_picture_drag_prepare,
|
||||
"on_picture_drop", (GCallback)on_picture_drop,
|
||||
"tab_close_cb", (GCallback)tab_close_cb,
|
||||
"increase_icon_size", (GCallback)increase_icon_size,
|
||||
"decrease_icon_size", (GCallback)decrease_icon_size,
|
||||
"reset_icon_size", (GCallback)reset_icon_size,
|
||||
"osd_frame_pressed", (GCallback)osd_frame_pressed,
|
||||
"age_entry_changed", (GCallback)age_entry_changed,
|
||||
"validate_more_details", (GCallback)validate_more_details,
|
||||
"mode_switch_state_set", (GCallback)mode_switch_state_set,
|
||||
"level_scale_value_changed", (GCallback)level_scale_value_changed,
|
||||
"transition_speed_changed", (GCallback)transition_speed_changed,
|
||||
NULL);
|
||||
gtk_builder_cscope_add_callback (scope, on_entry_icon_release);
|
||||
gtk_builder_cscope_add_callback (scope, on_scale_button_value_changed);
|
||||
gtk_builder_cscope_add_callback (scope, on_record_button_toggled);
|
||||
gtk_builder_cscope_add_callback (scope, on_page_combo_changed);
|
||||
gtk_builder_cscope_add_callback (scope, on_range_from_changed);
|
||||
gtk_builder_cscope_add_callback (scope, on_range_to_changed);
|
||||
gtk_builder_cscope_add_callback (scope, on_picture_drag_prepare);
|
||||
gtk_builder_cscope_add_callback (scope, on_picture_drop);
|
||||
gtk_builder_cscope_add_callback (scope, tab_close_cb);
|
||||
gtk_builder_cscope_add_callback (scope, increase_icon_size);
|
||||
gtk_builder_cscope_add_callback (scope, decrease_icon_size);
|
||||
gtk_builder_cscope_add_callback (scope, osd_frame_pressed);
|
||||
gtk_builder_cscope_add_callback (scope, age_entry_changed);
|
||||
gtk_builder_cscope_add_callback (scope, validate_more_details);
|
||||
gtk_builder_cscope_add_callback (scope, mode_switch_state_set);
|
||||
gtk_builder_cscope_add_callback (scope, level_scale_value_changed);
|
||||
gtk_builder_cscope_add_callback (scope, transition_speed_changed);
|
||||
gtk_builder_set_scope (builder, scope);
|
||||
g_object_unref (scope);
|
||||
if (!gtk_builder_add_from_resource (builder, "/org/gtk/WidgetFactory4/widget-factory.ui", &error))
|
||||
|
||||
@@ -5,7 +5,7 @@ repository_url = "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
website_url = "https://www.gtk.org"
|
||||
authors = "GTK Development Team"
|
||||
logo_url = "gtk-logo.svg"
|
||||
license = "GPL-2.1-or-later"
|
||||
license = "LGPL-2.1-or-later"
|
||||
description = "The GTK toolkit"
|
||||
devhelp = true
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ repository_url = "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
website_url = "https://www.gtk.org"
|
||||
authors = "GTK Development Team"
|
||||
logo_url = "gtk-logo.svg"
|
||||
license = "GPL-2.1-or-later"
|
||||
license = "LGPL-2.1-or-later"
|
||||
description = "The GTK toolkit"
|
||||
dependencies = ["Gdk-4.0"]
|
||||
devhelp = true
|
||||
|
||||
@@ -354,6 +354,7 @@ typedef struct {
|
||||
|
||||
typedef union {
|
||||
BroadwayReplyBase base;
|
||||
BroadwayReplySync sync;
|
||||
BroadwayReplyEvent event;
|
||||
BroadwayReplyQueryMouse query_mouse;
|
||||
BroadwayReplyNewSurface new_surface;
|
||||
|
||||
@@ -219,11 +219,7 @@ static void
|
||||
client_handle_request (BroadwayClient *client,
|
||||
BroadwayRequest *request)
|
||||
{
|
||||
BroadwayReplyNewSurface reply_new_surface;
|
||||
BroadwayReplySync reply_sync;
|
||||
BroadwayReplyQueryMouse reply_query_mouse;
|
||||
BroadwayReplyGrabPointer reply_grab_pointer;
|
||||
BroadwayReplyUngrabPointer reply_ungrab_pointer;
|
||||
BroadwayReply reply;
|
||||
guint32 before_serial, now_serial;
|
||||
guint32 global_id;
|
||||
int fd;
|
||||
@@ -233,7 +229,7 @@ client_handle_request (BroadwayClient *client,
|
||||
switch (request->base.type)
|
||||
{
|
||||
case BROADWAY_REQUEST_NEW_SURFACE:
|
||||
reply_new_surface.id =
|
||||
reply.new_surface.id =
|
||||
broadway_server_new_surface (server, client->id,
|
||||
request->new_surface.x,
|
||||
request->new_surface.y,
|
||||
@@ -241,9 +237,9 @@ client_handle_request (BroadwayClient *client,
|
||||
request->new_surface.height);
|
||||
client->surfaces =
|
||||
g_list_prepend (client->surfaces,
|
||||
GUINT_TO_POINTER (reply_new_surface.id));
|
||||
GUINT_TO_POINTER (reply.new_surface.id));
|
||||
|
||||
send_reply (client, request, (BroadwayReply *)&reply_new_surface, sizeof (reply_new_surface),
|
||||
send_reply (client, request, &reply, sizeof (reply.new_surface),
|
||||
BROADWAY_REPLY_NEW_SURFACE);
|
||||
break;
|
||||
case BROADWAY_REQUEST_FLUSH:
|
||||
@@ -251,7 +247,7 @@ client_handle_request (BroadwayClient *client,
|
||||
break;
|
||||
case BROADWAY_REQUEST_SYNC:
|
||||
broadway_server_flush (server);
|
||||
send_reply (client, request, (BroadwayReply *)&reply_sync, sizeof (reply_sync),
|
||||
send_reply (client, request, &reply, sizeof (reply.sync),
|
||||
BROADWAY_REPLY_SYNC);
|
||||
break;
|
||||
case BROADWAY_REQUEST_ROUNDTRIP:
|
||||
@@ -261,11 +257,11 @@ client_handle_request (BroadwayClient *client,
|
||||
break;
|
||||
case BROADWAY_REQUEST_QUERY_MOUSE:
|
||||
broadway_server_query_mouse (server,
|
||||
&reply_query_mouse.surface,
|
||||
&reply_query_mouse.root_x,
|
||||
&reply_query_mouse.root_y,
|
||||
&reply_query_mouse.mask);
|
||||
send_reply (client, request, (BroadwayReply *)&reply_query_mouse, sizeof (reply_query_mouse),
|
||||
&reply.query_mouse.surface,
|
||||
&reply.query_mouse.root_x,
|
||||
&reply.query_mouse.root_y,
|
||||
&reply.query_mouse.mask);
|
||||
send_reply (client, request, &reply, sizeof (reply.query_mouse),
|
||||
BROADWAY_REPLY_QUERY_MOUSE);
|
||||
break;
|
||||
case BROADWAY_REQUEST_DESTROY_SURFACE:
|
||||
@@ -361,21 +357,21 @@ client_handle_request (BroadwayClient *client,
|
||||
request->move_resize.height);
|
||||
break;
|
||||
case BROADWAY_REQUEST_GRAB_POINTER:
|
||||
reply_grab_pointer.status =
|
||||
reply.grab_pointer.status =
|
||||
broadway_server_grab_pointer (server,
|
||||
client->id,
|
||||
request->grab_pointer.id,
|
||||
request->grab_pointer.owner_events,
|
||||
request->grab_pointer.event_mask,
|
||||
request->grab_pointer.time_);
|
||||
send_reply (client, request, (BroadwayReply *)&reply_grab_pointer, sizeof (reply_grab_pointer),
|
||||
send_reply (client, request, &reply, sizeof (reply.grab_pointer),
|
||||
BROADWAY_REPLY_GRAB_POINTER);
|
||||
break;
|
||||
case BROADWAY_REQUEST_UNGRAB_POINTER:
|
||||
reply_ungrab_pointer.status =
|
||||
reply.ungrab_pointer.status =
|
||||
broadway_server_ungrab_pointer (server,
|
||||
request->ungrab_pointer.time_);
|
||||
send_reply (client, request, (BroadwayReply *)&reply_ungrab_pointer, sizeof (reply_ungrab_pointer),
|
||||
send_reply (client, request, &reply, sizeof (reply.ungrab_pointer),
|
||||
BROADWAY_REPLY_UNGRAB_POINTER);
|
||||
break;
|
||||
case BROADWAY_REQUEST_FOCUS_SURFACE:
|
||||
|
||||
@@ -189,8 +189,7 @@ _gdk_broadway_events_got_input (GdkDisplay *display,
|
||||
message->pointer.state,
|
||||
message->scroll.dir == 0
|
||||
? GDK_SCROLL_UP
|
||||
: GDK_SCROLL_DOWN,
|
||||
FALSE);
|
||||
: GDK_SCROLL_DOWN);
|
||||
|
||||
node = _gdk_event_queue_append (display, event);
|
||||
_gdk_windowing_got_event (display, node, event, message->base.serial);
|
||||
|
||||
@@ -90,10 +90,10 @@ _gdk_broadway_display_get_keymap (GdkDisplay *display)
|
||||
return broadway_display->keymap;
|
||||
}
|
||||
|
||||
static PangoDirection
|
||||
static Pango2Direction
|
||||
gdk_broadway_keymap_get_direction (GdkKeymap *keymap)
|
||||
{
|
||||
return PANGO_DIRECTION_NEUTRAL;
|
||||
return PANGO2_DIRECTION_NEUTRAL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
||||
@@ -28,8 +28,8 @@ gboolean gdk_should_use_portal (void);
|
||||
|
||||
const char * gdk_get_startup_notification_id (void);
|
||||
|
||||
PangoDirection gdk_unichar_direction (gunichar ch) G_GNUC_CONST;
|
||||
PangoDirection gdk_find_base_dir (const char *text,
|
||||
Pango2Direction gdk_unichar_direction (gunichar ch) G_GNUC_CONST;
|
||||
Pango2Direction gdk_find_base_dir (const char *text,
|
||||
int len);
|
||||
|
||||
typedef struct
|
||||
|
||||
35
gdk/gdk.c
35
gdk/gdk.c
@@ -117,6 +117,7 @@ static const GdkDebugKey gdk_debug_keys[] = {
|
||||
{ "selection", GDK_DEBUG_SELECTION, "Information about selections" },
|
||||
{ "clipboard", GDK_DEBUG_CLIPBOARD, "Information about clipboards" },
|
||||
{ "nograbs", GDK_DEBUG_NOGRABS, "Disable pointer and keyboard grabs (X11)" },
|
||||
{ "portals", GDK_DEBUG_PORTALS, "Force the use of portals" },
|
||||
{ "gl-disable", GDK_DEBUG_GL_DISABLE, "Disable OpenGL support" },
|
||||
{ "gl-software", GDK_DEBUG_GL_SOFTWARE, "Force OpenGL software rendering" },
|
||||
{ "gl-texture-rect", GDK_DEBUG_GL_TEXTURE_RECT, "Use OpenGL texture rectangle extension" },
|
||||
@@ -360,24 +361,16 @@ gdk_running_in_sandbox (void)
|
||||
gboolean
|
||||
gdk_should_use_portal (void)
|
||||
{
|
||||
static const char *use_portal = NULL;
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (NULL, PORTALS))
|
||||
return TRUE;
|
||||
|
||||
if (G_UNLIKELY (use_portal == NULL))
|
||||
{
|
||||
if (gdk_running_in_sandbox ())
|
||||
use_portal = "1";
|
||||
else
|
||||
{
|
||||
use_portal = g_getenv ("GTK_USE_PORTAL");
|
||||
if (!use_portal)
|
||||
use_portal = "";
|
||||
}
|
||||
}
|
||||
if (gdk_running_in_sandbox ())
|
||||
return TRUE;
|
||||
|
||||
return use_portal[0] == '1';
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
PangoDirection
|
||||
Pango2Direction
|
||||
gdk_unichar_direction (gunichar ch)
|
||||
{
|
||||
FriBidiCharType fribidi_ch_type;
|
||||
@@ -387,21 +380,21 @@ gdk_unichar_direction (gunichar ch)
|
||||
fribidi_ch_type = fribidi_get_bidi_type (ch);
|
||||
|
||||
if (!FRIBIDI_IS_STRONG (fribidi_ch_type))
|
||||
return PANGO_DIRECTION_NEUTRAL;
|
||||
return PANGO2_DIRECTION_NEUTRAL;
|
||||
else if (FRIBIDI_IS_RTL (fribidi_ch_type))
|
||||
return PANGO_DIRECTION_RTL;
|
||||
return PANGO2_DIRECTION_RTL;
|
||||
else
|
||||
return PANGO_DIRECTION_LTR;
|
||||
return PANGO2_DIRECTION_LTR;
|
||||
}
|
||||
|
||||
PangoDirection
|
||||
Pango2Direction
|
||||
gdk_find_base_dir (const char *text,
|
||||
int length)
|
||||
{
|
||||
PangoDirection dir = PANGO_DIRECTION_NEUTRAL;
|
||||
Pango2Direction dir = PANGO2_DIRECTION_NEUTRAL;
|
||||
const char *p;
|
||||
|
||||
g_return_val_if_fail (text != NULL || length == 0, PANGO_DIRECTION_NEUTRAL);
|
||||
g_return_val_if_fail (text != NULL || length == 0, PANGO2_DIRECTION_NEUTRAL);
|
||||
|
||||
p = text;
|
||||
while ((length < 0 || p < text + length) && *p)
|
||||
@@ -410,7 +403,7 @@ gdk_find_base_dir (const char *text,
|
||||
|
||||
dir = gdk_unichar_direction (wc);
|
||||
|
||||
if (dir != PANGO_DIRECTION_NEUTRAL)
|
||||
if (dir != PANGO2_DIRECTION_NEUTRAL)
|
||||
break;
|
||||
|
||||
p = g_utf8_next_char (p);
|
||||
|
||||
@@ -125,7 +125,7 @@ gdk_app_launch_context_class_init (GdkAppLaunchContextClass *klass)
|
||||
* The display that the `GdkAppLaunchContext` is on.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class, PROP_DISPLAY,
|
||||
g_param_spec_object ("display", P_("Display"), P_("Display"),
|
||||
g_param_spec_object ("display", NULL, NULL,
|
||||
GDK_TYPE_DISPLAY,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
#include <gdk/gdkrgba.h>
|
||||
#include <gdk/gdkpixbuf.h>
|
||||
#include <pango/pangocairo.h>
|
||||
#include <pango2/pangocairo.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
@@ -357,9 +357,7 @@ gdk_clipboard_class_init (GdkClipboardClass *class)
|
||||
* The `GdkDisplay` that the clipboard belongs to.
|
||||
*/
|
||||
properties[PROP_DISPLAY] =
|
||||
g_param_spec_object ("display",
|
||||
"Display",
|
||||
"Display owning this clipboard",
|
||||
g_param_spec_object ("display", NULL, NULL,
|
||||
GDK_TYPE_DISPLAY,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
@@ -372,9 +370,7 @@ gdk_clipboard_class_init (GdkClipboardClass *class)
|
||||
* The possible formats that the clipboard can provide its data in.
|
||||
*/
|
||||
properties[PROP_FORMATS] =
|
||||
g_param_spec_boxed ("formats",
|
||||
"Formats",
|
||||
"The possible formats for data",
|
||||
g_param_spec_boxed ("formats", NULL, NULL,
|
||||
GDK_TYPE_CONTENT_FORMATS,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
@@ -386,9 +382,7 @@ gdk_clipboard_class_init (GdkClipboardClass *class)
|
||||
* %TRUE if the contents of the clipboard are owned by this process.
|
||||
*/
|
||||
properties[PROP_LOCAL] =
|
||||
g_param_spec_boolean ("local",
|
||||
"Local",
|
||||
"If the contents are owned by this process",
|
||||
g_param_spec_boolean ("local", NULL, NULL,
|
||||
TRUE,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
@@ -401,9 +395,7 @@ gdk_clipboard_class_init (GdkClipboardClass *class)
|
||||
* provided otherwise.
|
||||
*/
|
||||
properties[PROP_CONTENT] =
|
||||
g_param_spec_object ("content",
|
||||
"Content",
|
||||
"Provider of the clipboard's content",
|
||||
g_param_spec_object ("content", NULL, NULL,
|
||||
GDK_TYPE_CONTENT_PROVIDER,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
|
||||
@@ -173,9 +173,7 @@ gdk_content_provider_class_init (GdkContentProviderClass *class)
|
||||
* The possible formats that the provider can provide its data in.
|
||||
*/
|
||||
properties[PROP_FORMATS] =
|
||||
g_param_spec_boxed ("formats",
|
||||
"Formats",
|
||||
"The possible formats for data",
|
||||
g_param_spec_boxed ("formats", NULL, NULL,
|
||||
GDK_TYPE_CONTENT_FORMATS,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
@@ -187,9 +185,7 @@ gdk_content_provider_class_init (GdkContentProviderClass *class)
|
||||
* The subset of formats that clipboard managers should store this provider's data in.
|
||||
*/
|
||||
properties[PROP_STORABLE_FORMATS] =
|
||||
g_param_spec_boxed ("storable-formats",
|
||||
"Storable formats",
|
||||
"The formats that data should be stored in",
|
||||
g_param_spec_boxed ("storable-formats", NULL, NULL,
|
||||
GDK_TYPE_CONTENT_FORMATS,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
|
||||
@@ -174,9 +174,7 @@ gdk_cursor_class_init (GdkCursorClass *cursor_class)
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_FALLBACK,
|
||||
g_param_spec_object ("fallback",
|
||||
P_("Fallback"),
|
||||
P_("Cursor image to fall back to if this cursor cannot be displayed"),
|
||||
g_param_spec_object ("fallback", NULL, NULL,
|
||||
GDK_TYPE_CURSOR,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
@@ -188,9 +186,7 @@ gdk_cursor_class_init (GdkCursorClass *cursor_class)
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_HOTSPOT_X,
|
||||
g_param_spec_int ("hotspot-x",
|
||||
P_("Hotspot X"),
|
||||
P_("Horizontal offset of the cursor hotspot"),
|
||||
g_param_spec_int ("hotspot-x", NULL, NULL,
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
@@ -202,9 +198,7 @@ gdk_cursor_class_init (GdkCursorClass *cursor_class)
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_HOTSPOT_Y,
|
||||
g_param_spec_int ("hotspot-y",
|
||||
P_("Hotspot Y"),
|
||||
P_("Vertical offset of the cursor hotspot"),
|
||||
g_param_spec_int ("hotspot-y", NULL, NULL,
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
@@ -218,9 +212,7 @@ gdk_cursor_class_init (GdkCursorClass *cursor_class)
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_NAME,
|
||||
g_param_spec_string ("name",
|
||||
P_("Name"),
|
||||
P_("Name of this cursor"),
|
||||
g_param_spec_string ("name", NULL, NULL,
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
@@ -234,9 +226,7 @@ gdk_cursor_class_init (GdkCursorClass *cursor_class)
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_TEXTURE,
|
||||
g_param_spec_object ("texture",
|
||||
P_("Texture"),
|
||||
P_("The texture displayed by this cursor"),
|
||||
g_param_spec_object ("texture", NULL, NULL,
|
||||
GDK_TYPE_TEXTURE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
@@ -38,19 +38,20 @@ typedef enum {
|
||||
GDK_DEBUG_CLIPBOARD = 1 << 10,
|
||||
/* flags below are influencing behavior */
|
||||
GDK_DEBUG_NOGRABS = 1 << 11,
|
||||
GDK_DEBUG_GL_DISABLE = 1 << 12,
|
||||
GDK_DEBUG_GL_SOFTWARE = 1 << 13,
|
||||
GDK_DEBUG_GL_TEXTURE_RECT = 1 << 14,
|
||||
GDK_DEBUG_GL_LEGACY = 1 << 15,
|
||||
GDK_DEBUG_GL_GLES = 1 << 16,
|
||||
GDK_DEBUG_GL_DEBUG = 1 << 17,
|
||||
GDK_DEBUG_GL_EGL = 1 << 18,
|
||||
GDK_DEBUG_GL_GLX = 1 << 19,
|
||||
GDK_DEBUG_GL_WGL = 1 << 20,
|
||||
GDK_DEBUG_VULKAN_DISABLE = 1 << 21,
|
||||
GDK_DEBUG_VULKAN_VALIDATE = 1 << 22,
|
||||
GDK_DEBUG_DEFAULT_SETTINGS= 1 << 23,
|
||||
GDK_DEBUG_HIGH_DEPTH = 1 << 24,
|
||||
GDK_DEBUG_PORTALS = 1 << 12,
|
||||
GDK_DEBUG_GL_DISABLE = 1 << 13,
|
||||
GDK_DEBUG_GL_SOFTWARE = 1 << 14,
|
||||
GDK_DEBUG_GL_TEXTURE_RECT = 1 << 15,
|
||||
GDK_DEBUG_GL_LEGACY = 1 << 16,
|
||||
GDK_DEBUG_GL_GLES = 1 << 17,
|
||||
GDK_DEBUG_GL_DEBUG = 1 << 18,
|
||||
GDK_DEBUG_GL_EGL = 1 << 19,
|
||||
GDK_DEBUG_GL_GLX = 1 << 20,
|
||||
GDK_DEBUG_GL_WGL = 1 << 21,
|
||||
GDK_DEBUG_VULKAN_DISABLE = 1 << 22,
|
||||
GDK_DEBUG_VULKAN_VALIDATE = 1 << 23,
|
||||
GDK_DEBUG_DEFAULT_SETTINGS= 1 << 24,
|
||||
GDK_DEBUG_HIGH_DEPTH = 1 << 25,
|
||||
} GdkDebugFlags;
|
||||
|
||||
extern guint _gdk_debug_flags;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user