Compare commits

..

218 Commits

Author SHA1 Message Date
Matthias Clasen 2a79ed5463 wip: pathbuilder: Hide artificial joins
When splitting quads or cubics at cusps, add
a single-point quad to indicate that we want
a round join here.
2023-09-20 22:44:25 -04:00
Matthias Clasen ef6d3af6b9 Merge branch 'revert-sassc-wrapdb' into 'main'
Revert "build-aux/flatpak: use sassc from wrapdb"

See merge request GNOME/gtk!6415
2023-09-20 22:46:33 +00:00
Christoph Reiter f513914306 Revert "meson: Move libsass/sassc subprojects to use wrapdb"
This reverts commit 7eb999720a.
2023-09-19 21:28:28 +02:00
Christoph Reiter 7135f80094 Revert "build-aux/flatpak: use sassc from wrapdb"
This reverts commit cac0cb7f02.

This doesn't work since CI currently mixes flatpak-builder and the host git repo
and doesn't download the gtk sources, so all subprojects are missing.
2023-09-19 21:27:46 +02:00
Matthias Clasen ef82e0ce4e Merge branch 'matthiasc/for-main' into 'main'
gtk4-demo: Fix a crash

Closes #6107

See merge request GNOME/gtk!6413
2023-09-19 19:12:58 +00:00
Matthias Clasen 1910834f8f Merge branch 'sassc-wrapdb' into 'main'
meson: Move libsass/sassc subprojects to use wrapdb

See merge request GNOME/gtk!6410
2023-09-19 18:49:50 +00:00
Matthias Clasen f94a0624fa gtk4-demo: Fix a crash
This conversion of GtkStatusbar was a bit too
quick.

Fixes: #6107
2023-09-19 14:47:59 -04:00
Andre Klapper 56c0aa596e DOAP: Replace non-existing mailing lists with GNOME Discourse URL 2023-09-19 18:21:17 +02:00
Sabri Ünal a1c73a9b2e Update Turkish translation 2023-09-19 15:36:36 +00:00
Christoph Reiter cac0cb7f02 build-aux/flatpak: use sassc from wrapdb
Instead of building the projects from my forks, build them as gtk
subprojects.

To avoid meson hitting the network for those wraps, add the required
files as extra sources and put them into subprojects/packagecache,
so meson can find them at build time.
2023-09-19 17:25:28 +02:00
Christoph Reiter 7eb999720a meson: Move libsass/sassc subprojects to use wrapdb
They were pointing to my personal fork, but I've now added
them to wrapdb:

* https://github.com/mesonbuild/wrapdb/pull/1153
* https://github.com/mesonbuild/wrapdb/pull/1185
2023-09-19 16:51:53 +02:00
Nathan Follens 05e15241b4 Update Dutch translation
(cherry picked from commit d66f590a86)
2023-09-19 12:31:41 +00:00
Boyuan Yang a730867778 Update Chinese (China) translation 2023-09-19 01:47:20 +00:00
Matthias Clasen 8513621709 Merge branch 'wip/carlosg/for-main' into 'main'
Some fixes

Closes #5820, #6098, and #5529

See merge request GNOME/gtk!6407
2023-09-18 22:28:10 +00:00
Carlos Garnacho 14d99bacbc gdk/wayland: Use toplevel surface for activation
At the moment of launching/activating an application, the
keyboard focus may be on a transient surface that quickly
disappears after activation. If this happens, and the
compositor handles surface destruction before the activated
application gets to reply, the activation request may be
deemed outdated, and the "demands attention" paths be taken.

Peek the toplevel from the focus surface, as that has larger
guarantees to remain valid for the whole duration of the
operation.

Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5820
2023-09-18 22:04:32 +02:00
Carlos Garnacho cbbd3e8fc3 demos: Add step/page-increment to path_walk demo spinbutton
It had 0 defaults, so it didn't get to spin when interacted.

Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/6098
2023-09-18 20:09:42 +02:00
Carlos Garnacho 8fa45d5fef gtkwindow: Pick a suitable widget to continue the implicit grab
When a widget in the GtkPointerFocus stack becomes insensitive, we've
so far broken the implicit grab entirely. This has the side effect of
breaking accounting of the active state on the widgets that are
ancestors of the widget that became insensitive.

The easiest, and most consistent thing to do (i.e. giving widgets
in the GtkPointerFocus stack certain level of isolation wrt state
changes in other widgets) is to transfer the implicit grab to the
topmost actor of the GtkPointerFocus stack that can keep handling
events.

This fixes the unbalanced accounting of active state on ancestors
of widgets becoming insensitive, and avoids thorny questions about
how to handle implicit active state with broken implicit grabs.
2023-09-18 19:53:33 +02:00
Carlos Garnacho 3e1706679c gtkwindow: Clear active state on sensitiveness changes
When altering the broken implicit grab due to sensitiveness changes,
also ensure to clear the active state from the affected actors. This
fixes unbalanced implicit active state accounting on the widgets going
insensitive.

Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5529
2023-09-18 19:50:53 +02:00
Carlos Garnacho 7f359e31c6 gtkmain: Drop redundant code
The common ancestor is already figured out at the beginning of the
function, no need to find it again.
2023-09-18 16:56:29 +02:00
Rūdolfs Mazurs e4af2c4d80 Update Latvian translation
(cherry picked from commit 7b6b31f0d8)
2023-09-18 13:29:58 +00:00
Matthias Clasen 2d121c07c9 Merge branch 'default_theme_relative_font_sizes' into 'main'
theme: use relative font sizes

See merge request GNOME/gtk!6372
2023-09-18 11:16:10 +00:00
Matthias Clasen cc904698a6 Merge branch 'matthiasc/for-main' into 'main'
contour: Make circles and rounded rects match

See merge request GNOME/gtk!6405
2023-09-18 11:14:39 +00:00
Matthias Clasen a5fdd1228f Merge branch 'focus-on-click' into 'main'
Focus-on-click improvements

See merge request GNOME/gtk!6336
2023-09-18 10:41:52 +00:00
Sergey Bugaev 271d7632cb text: Respect focus-on-click property
It does make sense to have GtkText not focus on click in some cases,
such as when its editable property is set to false.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2023-09-18 12:03:54 +03:00
Sergey Bugaev a8613377a5 colorbutton, fontbutton: Propagate focus-on-click to inner buttons
These widgets wrap a GtkButton internally. Make it possible to prevent
the inner button from grabbing focus on click by propagating the value
of the focus-on-click property from the widget to the inner button.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2023-09-18 12:03:54 +03:00
Benjamin Otte d7cf5c2b1b Merge branch 'wip/otte/for-main' into 'main'
gl: gradients should transition in unpremultiplied space

See merge request GNOME/gtk!6406
2023-09-18 06:20:32 +00:00
Benjamin Otte 95865cb1bf gsk: Fix clipping error when drawing shadows
When shadows were offset - in particular when offset so the original
source was out of bounds of the result - the drawing code would create a
pattern for it that didn't include enough of it to compose a shadow.

Fix that by not creating those patterns anymore, but instead drawing the
source (potentially multiple times) at the required offsets.

While that does more drawing, it simplifies the shadow node draw code,
and that's the primary goal of the Cairo rendering.

Test included.
2023-09-18 07:53:03 +02:00
Benjamin Otte 0b813de72a gl: gradients should transition in unpremultiplied space
So make the gradient shaders do that.
2023-09-18 07:53:03 +02:00
Matthias Clasen 9c159cf129 path: Tweak printing a bit more
We are dealing with floats here, so using
g_ascii_dtostr isn't really the best.

Update affected tests.
2023-09-17 22:35:33 -04:00
Matthias Clasen 957d494090 contour: Make circles and rounded rects match
Make sure that we print the weights in the
same way (as floats).

Update affected tests.
2023-09-17 20:32:32 -04:00
Matthias Clasen 968b4237a9 Merge branch 'matthiasc/for-main' into 'main'
path: Fix parsing rounded rects

See merge request GNOME/gtk!6404
2023-09-17 21:19:42 +00:00
Matthias Clasen f67c57b1f8 path: Fix parsing rounded rects
We were messing up the bottom left corner.

Test included.
2023-09-17 17:01:44 -04:00
Matthias Clasen 84f8c2d91d Merge branch 'matthiasc/for-main' into 'main'
inspector: Don't set a NULL fontdesc

Closes #5988

See merge request GNOME/gtk!6403
2023-09-17 19:17:28 +00:00
Matthias Clasen 8f1d8d7cb5 path: Split off gskpathparse.c
This is a standalone piece of code,
and nicely fits into its own source file.
2023-09-17 12:29:46 -04:00
Matthias Clasen e98d9d62eb inspector: Don't set a NULL fontdesc
The font dialog button does not like that.

Fixes: #5988
2023-09-17 10:19:05 -04:00
Matthias Clasen 5a0b65c611 Merge branch 'path-builder-simplify' into 'main'
pathbuilder: Simplify degenerate curves

See merge request GNOME/gtk!6402
2023-09-17 13:55:32 +00:00
Matthias Clasen 5777587e7a docs: Add details for GskPathBuilder
Mention that GskPathBuilder will simplify
added Bézier curves.
2023-09-17 09:31:59 -04:00
Matthias Clasen ecfc661054 Adapt tests to new path builder behavior
Some tests were expecting to get elevated curves
from GskPathBuilder. But they won't, anymore.
2023-09-17 08:53:10 -04:00
Emmanuele Bassi e00722dee6 Merge branch 'submenu_reporting' into 'main'
a11y: When a menu item opens a submenu, set its expandable state

See merge request GNOME/gtk!5850
2023-09-17 11:02:33 +00:00
Piotr Drąg 5af21e70ec Update Polish translation 2023-09-17 12:15:52 +02:00
Matthias Clasen 7e13cfea91 path builder: Handle degenerate cubics
Replace cubics by lines or quadratics
when possible, and split at cusps.
2023-09-17 00:23:53 -04:00
Matthias Clasen 68b4d9c35e Add gsk_curve_get_cusps 2023-09-17 00:23:53 -04:00
Matthias Clasen 1f3b69e7db path builder: Handle degenerate conics
Do the same we do for quads here. Also,
conics with weight 1 are just quads.
2023-09-17 00:23:53 -04:00
Matthias Clasen ca63552cf8 path builder: Handle degenerate quads
Quads that have a cusp need to be replaced by
two lines.
2023-09-17 00:23:53 -04:00
Matthias Clasen a6d2d983b8 Add gsk_bounding_box_get_corner
This will be used in the following commits.
2023-09-16 21:57:31 -04:00
Matthias Clasen 7cd97192e5 pathbuilder: Simplify degenerate curves
When a quadratic or conic has identical points,
replace it with a line.
2023-09-16 14:32:12 -04:00
Matthias Clasen 8ac8bca52a Fix an indentation mishap 2023-09-16 13:39:21 -04:00
Benjamin Otte cf8f6d254e Merge branch 'wip/otte/for-main' into 'main'
treemodelfilter: Yes gcc, both if branches are empty

See merge request GNOME/gtk!6401
2023-09-16 17:07:10 +00:00
Benjamin Otte a267dfac5d treeview: No gcc, node is not NULL
... so I'll add an assertion just for you.
2023-09-16 12:18:58 -04:00
Benjamin Otte 745b28ef38 treemodelfilter: Yes gcc, both if branches are empty
... if assertions are disabled.
2023-09-16 12:17:57 -04:00
Matthias Clasen 5c27899efa Merge branch 'matthiasc/for-main' into 'main'
NEWS: Updates

See merge request GNOME/gtk!6400
2023-09-16 15:23:02 +00:00
Matthias Clasen fd006592b5 Merge branch 'wip/corey/file-chooser-columns' into 'main'
File Chooser Move Column Visible to Column Header Menu

See merge request GNOME/gtk!6377
2023-09-16 14:27:52 +00:00
Matthias Clasen 201f27fe19 NEWS: Updates 2023-09-16 09:52:18 -04:00
Matthias Clasen 36c4dc8aea Merge branch 'contour-cosmetics' into 'main'
contour: Fixes for circles

See merge request GNOME/gtk!6399
2023-09-16 13:18:29 +00:00
Matthias Clasen f0bd0c3e50 contour: Add more tests for circles
Cover the radius 0 case, in particular.
2023-09-16 08:31:52 -04:00
Matthias Clasen 4d71ff6da1 contour: Fixes for circles
Make circle contours use 'foreach coordinates' for
its points. This works here, but not for general
conics. As with the other custom contours, avoid
emitting collapsed conics.
2023-09-16 08:27:18 -04:00
Matthias Clasen 6d16776e27 tests: Cosmetics 2023-09-16 08:27:08 -04:00
Piotr Drąg 7cdff6bbb3 Update Polish translation 2023-09-16 13:34:39 +02:00
Martin bf43859bdc Update Slovenian translation
(cherry picked from commit f0e0332ada)
2023-09-16 10:12:14 +00:00
Matthias Clasen 4b45f8415f Merge branch 'contour-cosmetics' into 'main'
contour: Fixes for rects and rounded rects

See merge request GNOME/gtk!6397
2023-09-15 22:30:13 +00:00
Matthias Clasen 86e0d5c13e Merge branch 'switch-rtl' into 'main'
switch: Respect text direction

Closes #1489

See merge request GNOME/gtk!6396
2023-09-15 21:59:15 +00:00
Matthias Clasen d21ee115d0 Update private path tests
Our parser only recognizes 'complete' rounded
rects, so don't test roundtrips for incomplete
ones.
2023-09-15 16:46:23 -04:00
Matthias Clasen 2dd8e3b0eb contour: Add more tests for rounded rects
This is covering special cases where some
of the curves are omitted.
2023-09-15 16:46:23 -04:00
Matthias Clasen 6d001f79f9 contour: Fixes for rounded rects
Similar to the fixes for rect contours:
Handle all the special cases where empty curves
are omitted, and omit 'empty' curves in foreach.
2023-09-15 16:31:09 -04:00
Matthias Clasen eb6ca8f39a contour: Add more tests for rects
Spot-check the special cases:
rects with zero height or width.
2023-09-15 16:31:09 -04:00
Matthias Clasen abebd92b19 contour: Fixes for rect contours
Handle all the special cases (zero width and/or height),
and omit 'empty' curves in foreach.
2023-09-15 16:31:09 -04:00
Matthias Clasen 014ca76334 docs: Add details
Spell out what gsk_path_point_get_tangent does
if there is no tangent: we return 0,0.
2023-09-15 16:31:09 -04:00
Matthias Clasen a520f9fcf7 pathbuilder: Skip trivial curves
Don't add quads, cubics or conics that collapse
to a single point. This matches what we do for
lines.
2023-09-15 16:31:09 -04:00
Matthias Clasen de724b2a57 contour: Fix some corner cases
Adding segments of rects or rounded rects was
not working right in cases where some of the
curves are trivial. Fix that.
2023-09-15 16:31:09 -04:00
Matthias Clasen 061637f4eb contour: Small refactoring
Move some utilities out.
2023-09-15 16:31:09 -04:00
Matthias Clasen dab1897d4e contour: Circle cosmetics 2023-09-15 16:31:09 -04:00
Andre Klapper 9ebb030c78 CONTRIBUTING: No more mailing lists; list Matrix/Discourse as irc.gnome.org is defunct 2023-09-15 22:26:44 +02:00
Benjamin Otte 93477ec019 Merge branch 'wip/otte/for-main' into 'main'
rendernode: Shadow nodes need offscreen for opacity

See merge request GNOME/gtk!6382
2023-09-15 16:08:42 +00:00
Benjamin Otte f2a71898b1 array: Add gdk_array_steal()
Like gdk_array_clear() but returns the previous contents.
2023-09-15 16:34:00 +02:00
Benjamin Otte 24048dce43 render-node-tool: Actually load files properly 2023-09-15 16:34:00 +02:00
Benjamin Otte 41af8ee2e2 testsuite: Add another test
his is the opposite of the test in 1502c21e97.

Also change the numbers in that test so it doesn't need a ref file.

Related: #6075
2023-09-15 16:34:00 +02:00
Benjamin Otte 60c20fa6ed vulkan: Require Vulkan 1.2
We need to inist on the nonuniform access beuing available and that
requires Vulkan 1.2.

Also simplifies the descriptor indexing stuff, because that's all part
of Vulkan 1.2, too.
2023-09-15 16:34:00 +02:00
Benjamin Otte 5152c13081 vulkan: Change rounded_rect_shrink()
Same fix as with the GL renderer
2023-09-15 16:34:00 +02:00
Benjamin Otte e9089f65e3 gl: Change rounded_rect_shrink()
The code now follows gsk_rounded_rect_shrink() and with it the behavior
of the Cairo renderer and Webkit.

The old code did what the GL renderer and Cairo do, but I consider that
wrong.

I did not test Chrome.

Test attached
2023-09-15 16:34:00 +02:00
Benjamin Otte 9aaec91f95 css: Snapshot opacity filter as opacity node
We were using color-matrix because it was easier, but opacity can often
be optimized when color-matrix needs offscreens.
2023-09-15 03:46:27 +02:00
Benjamin Otte 1c971c595f glrenderer: Shadows without offset do exist
Not for opaque contents, but stuff can be semi-transparent.

Testcase included.
2023-09-15 03:46:27 +02:00
Benjamin Otte f8627755b5 rendernode: Shadow nodes need offscreen for opacity
Otherwise the shadow will not be properly computed as opaque regions
become translucent after applying opacity.

Testcase included.
2023-09-15 03:46:27 +02:00
Benjamin Otte 55ae8dc39e gsk: Move GskRoundedRect typedef
typedef should go into *types.h headers so that other headers only need
to include those.
2023-09-15 03:46:27 +02:00
Matthias Clasen dd7d145249 Merge branch 'matthiasc/for-main' into 'main'
gtk-demo: Add sound to the path maze

See merge request GNOME/gtk!6395
2023-09-14 18:24:09 +00:00
Sergey Bugaev 0b2c249de3 switch: Fix CSS nodes documentation
A switch contains two GtkImage's whose nodes are named 'image',
not 'label'.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2023-09-14 19:35:00 +03:00
Sergey Bugaev ea6b95f60d switch: Respect text direction
In RTL, we want the active state to mean the handle is on the left.

Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/1489

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2023-09-14 19:35:00 +03:00
Matthias Clasen ed44f37de4 gtk-demo: Add sound to the path maze
Its a game, after all.
2023-09-14 11:32:22 -04:00
Matthias Clasen 3780a5ed6a Merge branch 'fix_visit_file' into 'main'
gtkfilechooserwidget: fix "Visit file" not scrolling to file

Closes #5799

See merge request GNOME/gtk!6392
2023-09-14 03:01:11 +00:00
Nelson Benítez León fec3f0191a gtkfilechooserwidget: fix "Visit file" not scrolling to file
In the "Recent" view of GtkFileChooser widget, when right
clicking and selecting "Visit file" action, the action was
failing to scroll to target file.

Fix that by using gtk_column_view_scroll_to() which can
select, focus and scroll to the file.

Fixes #5799
2023-09-13 23:47:47 +01:00
Matthias Clasen 359fa99945 Merge branch 'fun-renderer-bug' into 'main'
gl renderer: Keep track of source

Closes #6094

See merge request GNOME/gtk!6391
2023-09-13 21:31:30 +00:00
Matthias Clasen 5441ed2227 Merge branch 'mcatanzaro/put-event' into 'main'
Fix documentation of gdk_display_put_event()

See merge request GNOME/gtk!6383
2023-09-13 21:27:22 +00:00
Matthias Clasen ec1a1d0e34 gl renderer: Don't assume an atlas
The source uniform may or may not point
to a glyph atlas. The optimization we do
for color nodes is only possible if it does,
so check this.

Fixes: #6094
2023-09-13 16:56:47 -04:00
Matthias Clasen 8f4fb45715 gl renderer: Keep track of source
We have an optimization that depends on having
the source be a glyph atlas, so keep track of
that information in the render job.
2023-09-13 16:55:01 -04:00
Matthias Clasen 9db2288064 Merge branch 'matthiasc/for-main' into 'main'
rendernode: Fix handling of color glyphs

See merge request GNOME/gtk!6390
2023-09-13 20:14:41 +00:00
Matthias Clasen 1502c21e97 rendernode: Fix handling of color glyphs
The rendernode parser was mixing up its flags.

Test included.

Related: #6075
2023-09-13 15:37:57 -04:00
Matthias Clasen 408dd4b34d Merge branch 'macos' into 'main'
macOS: Clamp damage region to surface size

Closes #5812 and #6038

See merge request GNOME/gtk!6388
2023-09-13 15:33:01 +00:00
Luca Bacci 609e1f54ef macOS: Clamp damage region to surface size
...in _gdk_macos_cairo_context_begin_frame ()

GdkMacosCairoContext needs regions that are clamped to the
actual surface size.

Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/5812
2023-09-13 17:13:33 +02:00
Luca Bacci f49d0fbbf6 macOS: Fix typos 2023-09-13 16:53:27 +02:00
Michael Catanzaro dde47b7966 Fix documentation of gdk_display_put_event()
This function is deprecated, but we should still document it properly.
It appends, not prepends. This is clear enough from its implementation,
but also we have practical experience with WebKit in:

https://github.com/WebKit/WebKit/pull/8663

Matthias prefers to avoid the prepend, append, start, and end
terminology altogether.
2023-09-13 08:19:11 -05:00
Matthias Clasen f84da62740 Merge branch 'wip/corey/gridcell' into 'main'
gtkfilechoosercell: Don't use ColumnViewCell

See merge request GNOME/gtk!6378
2023-09-12 19:47:09 +00:00
Matthias Clasen cbfbe6dc23 Merge branch 'baseline-fixes' into 'main'
Baseline & measuring fixes

See merge request GNOME/gtk!6373
2023-09-12 19:46:12 +00:00
Corey Berla 2c63a34791 Apply 1 suggestion(s) to 1 file(s) 2023-09-12 17:05:33 +00:00
Matthias Clasen 9ab07553a3 Merge branch 'wip/fix-suspend-state' into 'main'
wayland: Bind correct xdg_wm_base version

See merge request GNOME/gtk!6385
2023-09-12 16:51:50 +00:00
Rafael Fontenelle c29fb838e9 Update Brazilian Portuguese translation
(cherry picked from commit 066b101c57)
2023-09-12 16:42:31 +00:00
Jonas Ådahl aecc76d916 wayland: Bind correct xdg_wm_base version
Otherwise we won't get the suspend state.
2023-09-12 21:51:59 +08:00
Michael Catanzaro 713a5188cf Fix typo 2023-09-08 11:46:26 -05:00
Changwoo Ryu 911f3bf555 Update Korean translation
(cherry picked from commit 1abfeff0d1)
2023-09-07 16:59:49 +00:00
Benjamin Otte c752598a3d Merge branch 'wip/otte/for-main' into 'main'
Various fixes

Closes #6083

See merge request GNOME/gtk!6380
2023-09-07 16:10:46 +00:00
Benjamin Otte 9dfdb1b65b rendernode-tool: Fix array size
Also add an assertion, so things explode properly if we forget to
update the array size when adding new nodes, instead of writing random
memory.
2023-09-07 16:19:20 +02:00
Benjamin Otte a05a021fd1 rendernode: Fix Cairo rendering of repeating gradients
Cairo and the GL renderer have a different idea of how to handle
transitioning of colors outside the defined range.

Consider these stops:
  black 50%, white 50%

What color is at 0%?

Cairo would transition between the last and first stop, ie it'd do a
white-to-black transition and end up at rgb(0.5,0.5,0.5) at 0%.
GL would behave as it would for non-repeating gradients and use black
for the range [0%..50%] and white for [50%..100%].
The web would rescale the range so the first stop would be at 0% and
the last stop would be at 100%, so this gradient would be illegal.

Considering that it's possible for code to transition between the
different behaviors by adding explicit stops at 0%/100%, I could choose
any method.
So I chose the simplest one, which is what the GL renderer does and
which treats repeating and non-repeating gradients the same.

Tests attached.
2023-09-07 16:19:20 +02:00
Benjamin Otte 9ffd7840ba pathpoint: Add G_GNUC_EXTENSION to struct definition
This allows compilation with gcc -pedantic.

GTKmm uses this as part of their recommended compiler flags.

Fixes #6083
2023-09-07 16:19:20 +02:00
Daniel Rusek dd64084b44 Update Czech translation 2023-09-07 13:42:13 +00:00
Bruce Cowan 21277a37d6 Update British English translation
(cherry picked from commit c71f8d0838)
2023-09-06 11:39:24 +00:00
Corey Berla ddc7e36543 gtkfilechoosercell: Don't use ColumnViewCell
This partially reverts ccae75022b.
Since FileChooserCell is used for ColumnView and GridView we should
treat the list item as a GtkListItem, not a ColumnViewCell otherwise
the menu fails to generate properly.
2023-09-05 12:45:34 -07:00
Corey Berla f429dff03e gtkfilechooserwidget: Move column menu items to the column header menu
The main menu is too long and the column options belong in the column
header menu to begin with.  Since this is only available in column
view, we should always show the menu items.
2023-09-05 12:24:27 -07:00
Corey Berla 6f07c6a3f1 gtkfilechooserwidget: Use property actions for column visibility
It's a lot less code
2023-09-05 12:24:27 -07:00
Corey Berla 4cb4aa1029 gtkfilechooserwidget: Bind column visibility to settings
It's less hacky and lets us drop even more code in the next commit.
2023-09-05 12:24:27 -07:00
Matthias Clasen cecab7801e Merge branch 'point-color' into 'main'
Point color

See merge request GNOME/gtk!6374
2023-09-04 06:03:22 +00:00
Matthias Clasen ea7fd1ff5a contour: Fixup for 1-point contours
If we return a path point for a 1-point contour,
make it { n, 0, 1 }.
2023-09-04 00:55:21 +02:00
Matthias Clasen ad474a60c0 path-tool: Update docs 2023-09-03 23:47:10 +02:00
Matthias Clasen 1e8e7e0c00 path-tool: Make render match show 2023-09-03 23:47:10 +02:00
Matthias Clasen 1e9e8d24c3 path-tool: Add a --point-color option 2023-09-03 23:47:10 +02:00
Matthias Clasen 9bd9b6f2ca contour: Make sure stroke bounds are sufficient 2023-09-03 23:04:47 +02:00
Aurimas Černius 913a6ddcc9 Update Lithuanian translation
(cherry picked from commit 5d54bb1359)
2023-09-03 18:20:17 +00:00
Sergey Bugaev 31da6f60d0 entry, searchentry: Fix measuring baseline
If the entry has icons, we may end up increasing our minimum and natural
height compared to the values the text child returned. In that case, we
should also adjust the baseline values to account for the text being
shifted down.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2023-09-03 21:07:52 +03:00
Sergey Bugaev c4c118e425 centerlayout: Fix measuring in presence of baselines
The measure logic (unlike the allocation logic) was enforcing strict
baseline alignment of child widgets even if no child widget had valign
set to baseline. This was causing GtkCenterLayout to request more size
than it actually needed.

Instead, bring the logic closer to that of GtkBoxLayout by introducing
explicit have_baseline and align_baseline variables. We track and report
baseline if have_baseline gets set, but it only affects our reported
minimum and natural sizes if align_baseline ends up set, which happens
if there's a child widget that has valign set to either one of the two
baseline values, and itself reports a valid baseline.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2023-09-03 21:07:52 +03:00
Ask Hjorth Larsen 02599acf4d Update Danish translation
(cherry picked from commit cc4d94d197)
2023-09-03 14:34:00 +00:00
Piotr Drąg 6a653e4675 Update POTFILES.in 2023-09-02 12:56:56 +02:00
Amn Alam 29e92d6a0e Update Punjabi translation 2023-09-02 04:21:39 +00:00
Ekaterine Papava b4fcc8b5f0 Update Georgian translation 2023-09-02 03:26:30 +00:00
G.Willems b00333c603 theme: use relative font sizes
This allows text to properly scale when changing the default font size.
2023-09-02 00:04:54 +02:00
Matthias Clasen 63614727a3 Merge branch 'matthiasc/for-main' into 'main'
path-tool: Factor out dash parsing

See merge request GNOME/gtk!6369
2023-08-31 12:06:47 +00:00
Matthias Clasen 061a56d213 path-tool: Add a way to show controls 2023-08-31 03:19:25 -04:00
Matthias Clasen 3f63ba36ce path-tool: Factor out dash parsing
No need to do this in two places.
2023-08-31 03:19:17 -04:00
Davide Ferracin d9b96c34be Update Italian translation
(cherry picked from commit 043c89dbe2)
2023-08-30 08:36:02 +00:00
Matthias Clasen 39a8c64624 Merge branch 'matthiasc/for-main' into 'main'
curve: Add a vfunc for get_at_length

See merge request GNOME/gtk!6366
2023-08-30 02:42:54 +00:00
Matthias Clasen 360b77cc50 curve: Add a vfunc for get_at_length
We can do this precisely for lines, so lets do it.
2023-08-29 22:09:59 -04:00
Matthias Clasen 1186eff1b7 Merge branch 'gtk-compose-test-case-single-char' into 'main'
composetable: Accept short compose sequences

See merge request GNOME/gtk!6358
2023-08-29 19:46:00 +00:00
Matthias Clasen 0b8582ccba Merge branch 'gsk-header-cleanup' into 'main'
gsk: Clean up standalone headers

See merge request GNOME/gtk!6364
2023-08-29 19:11:36 +00:00
Matthias Clasen dc2914e1f9 composetable: Warn for things we can't handle
The compose table stores the keyvals to match against
in a guint16 array, so it can't handle directly encoded
Unicode codepoints (which have a high bit set). Warn
if we encounter those.
2023-08-29 13:32:32 -04:00
Matthias Clasen a0d8678a9c composetable: Accept short compose sequences
Followup to 8931169e00. That commit did
not do enough work to actually accept sequences
of lenth 1, as pointed by Mike Fabian.
2023-08-29 13:30:05 -04:00
Mike FABIAN c8a43da526 Add test case for single char compose sequence 2023-08-29 13:30:05 -04:00
Matthias Clasen 90ee05ae64 gsk: Clean up standalone headers
We require folks to include gskglrenderer.h in order
to create a GL renderer. So we be careful to only
include header in gskglrenderer.h that won't trigger
ugly warnings.

See !6363
2023-08-29 12:58:30 -04:00
Matthias Clasen 67a7602080 Merge branch 'tests-svg-dimensions' into 'main'
testsuite/gsk: add explicit dimensions to <svg> elements

See merge request GNOME/gtk!6359
2023-08-29 04:43:22 +00:00
Matthias Clasen 37db270d19 Merge branch 'contour-foreach' into 'main'
Drop tolerance from gsk_contour_foreach

See merge request GNOME/gtk!6361
2023-08-29 01:58:39 +00:00
Matthias Clasen f3312f677b measure: Cosmetics 2023-08-28 21:14:28 -04:00
Matthias Clasen 05547d98d6 path: Cosmetics
Reorganize this source file into sections.
2023-08-28 21:13:58 -04:00
Matthias Clasen 11b219bc61 Drop tolerance from gsk_contour_foreach
There is no decomposition going on for any contours,
and the tolerance argument is entirely unused.
Decomposition and tolerance is handled entirely
in gskpath.c by its trampoline.
2023-08-28 20:52:22 -04:00
Matthias Clasen 5721c3cb8f demos: Drop an unused variable 2023-08-28 20:50:38 -04:00
Fran Dieguez f90ca697af Update Galician translation 2023-08-28 22:36:51 +00:00
Michael Orlitzky 7a0e27b6e8 testsuite/gsk: add explicit dimensions to <svg> elements
Without an explicit width, height, and viewBox, there is no single
correct way to render an SVG. In the absense of said information,
librsvg is capable of making a guess by rendering the SVG to a Cairo
surface and then analyzing that surface; however, this process is
merely heuristic.

There are three GTK tests for SVG images that are missing dimensions.
While this is not a violation of the SVG specification, it does
implicitly couple the test to the librsvg rendering heuristic. In this
commit we add that dimension information so that the expected result
is unambiguous.
2023-08-28 17:14:18 -04:00
Matthias Clasen e81aa18c82 Merge branch 'closest-point-distance' into 'main'
Change gsk_path_get_closest_point to return distance

See merge request GNOME/gtk!6357
2023-08-28 15:53:51 +00:00
Matthias Clasen 827bbc0cc1 Change gsk_path_get_closest_point to return distance
We already compute it, so lets return it.
Bindings seems fine with this change - they
already return (success, point) as a tuple
anyway.
2023-08-28 11:22:30 -04:00
Matthias Clasen 7095a67910 Merge branch 'matthiasc/for-main' into 'main'
path-tool: Add a reverse command

See merge request GNOME/gtk!6356
2023-08-28 04:38:42 +00:00
Matthias Clasen dcbca3f0d7 path-tool: Add a reverse command
It does what it says.
2023-08-28 00:27:29 -04:00
Matthias Clasen 702d7c238a Merge branch 'matthiasc/for-main' into 'main'
contour: Simplify gsk_circle_contour_foreach

See merge request GNOME/gtk!6355
2023-08-28 04:18:48 +00:00
Matthias Clasen 5a3ed65ad8 Improve precondition checks for path points
Add a helper function for checking that a
path point is valid for a path, and use it.
2023-08-28 00:07:50 -04:00
Matthias Clasen 2e24a9ece4 Make GskPathPoint public
The contents are still /*< private >*/, but we
let our tests and the debugger see them, which
helps.
2023-08-28 00:07:50 -04:00
Matthias Clasen 2a17320314 Limit rect variation in path builder
Make gsk_path_builder_add_rect always
produce a clockwise rectangle. This matches
what we do for circles and rounded rects,
which also go clockwise. Note that we
still need to allow negative widths in
the contour code, to implement reverse().
2023-08-28 00:07:50 -04:00
Matthias Clasen 0dbff14555 Allow circles with radius of zero
Not very useful, but we allow rects with
width and height of zero, so lets be consistent.
Curvature is infinite for such contours.

Tests included.
2023-08-28 00:07:50 -04:00
Matthias Clasen c5d89d00f1 Merge branch 'zbrown/tooltips' into 'main'
tooltip: don't cross native boundaries

Closes #1234, #5998, gnome-calendar#1038, and nautilus#3063

See merge request GNOME/gtk!6346
2023-08-28 03:25:44 +00:00
Matthias Clasen 6f3be310f4 contour: Simplify gsk_circle_contour_foreach
Use the same approach as the rounded rect contour.
2023-08-27 21:31:40 -04:00
Matthias Clasen 0ea6b70d55 Merge branch 'matthiasc/for-main' into 'main'
gtk-demo: Add a few path benchmarks

See merge request GNOME/gtk!6353
2023-08-27 23:45:59 +00:00
Matthias Clasen 2ca9982b91 rect contour: Avoid nans in corner cases
The length of rect contours can be zero,
so we much check before we divide.
2023-08-27 19:17:02 -04:00
Matthias Clasen a40282b2fb Add gsk_path_point_print
Another private debug API.
2023-08-27 19:06:39 -04:00
Matthias Clasen ad9fb1e101 Improve quad and conic decomposition
If the control point is equal to either
start or end, just emit a line. This improves
the rendering of rounded rectangles with such
corners.
2023-08-27 16:57:03 -04:00
Matthias Clasen 02a9652af4 Use a more compact representation for circles
Print circles as M-o-o-o-o-z.
2023-08-27 14:32:21 -04:00
Matthias Clasen 6f823d2d0d gtk-demo: Add a few path benchmarks
The Tiger and Graph examples in the fishbowl test
path handling.
2023-08-27 12:59:10 -04:00
Matthias Clasen a5c9cd5657 Merge branch 'rectangle-contour' into 'main'
Add a rectangle contour

See merge request GNOME/gtk!6351
2023-08-27 16:46:12 +00:00
Matthias Clasen 21ab5b6fa3 Merge branch 'matthiasc/for-main' into 'main'
Add a test for rectangle segments

See merge request GNOME/gtk!6352
2023-08-27 16:45:58 +00:00
Benjamin Otte 2582fd45e4 demos: Add cute maze demo 2023-08-27 12:45:25 -04:00
Matthias Clasen 0a28a5d53a Add a rectangle contour
Add a contour that optimizes some things for
rectangles. Also add rectangle detection to the
path parser, and add tests similar to what we
have for the other special contours.
2023-08-27 12:36:56 -04:00
Matthias Clasen ddd4855bbc Add a test for rectangle segments 2023-08-27 12:36:30 -04:00
Matthias Clasen 204216e3d5 Merge branch 'matthiasc/for-main' into 'main'
Drop unused code

See merge request GNOME/gtk!6350
2023-08-27 16:19:16 +00:00
Matthias Clasen 1e6a124665 Correct the docs of gsk_path_builder_add_rect
The path does *not* always go clockwise!
2023-08-27 12:18:36 -04:00
Matthias Clasen 78c5aff956 Test special contours harder
Check that the start- and endpoint work
as expected and verify that their winding
numbers match the ones of the standard contour,
and are negated when the contour is reversed.
2023-08-27 11:47:40 -04:00
Matthias Clasen 8d1844135b path: Add a comment 2023-08-27 10:10:08 -04:00
Matthias Clasen b5dd9dae0d rounded rect contour: Fix an oversight
The close operation takes 2 points, so our array
was one too short. Oops.
2023-08-27 10:09:32 -04:00
Matthias Clasen ebcb518e4f Cosmetics 2023-08-27 09:50:16 -04:00
Matthias Clasen b7ea22f168 Drop unused code
Nobody is calling gsk_contour_get_start_end, so drop
this internal API.
2023-08-27 09:39:59 -04:00
Matthias Clasen f0b3381660 Merge branch 'rounded-rect-contour' into 'main'
path: Add a rounded rect contour

See merge request GNOME/gtk!6347
2023-08-27 13:36:53 +00:00
Matthias Clasen 0796c72049 Add roundtrip tests for rounded rect contours
These should survive roundtrips through the
path parser as well now.
2023-08-27 09:31:17 -04:00
Matthias Clasen 822e988efe path: Recognize rounded rects when parsing
We can look out for M-L-O-L-O-L-O-L-O-Z patterns
with matching numbers.
2023-08-27 09:31:17 -04:00
Matthias Clasen cee043f977 Add a rounded rect contour
This special contour takes advantage of its
rounded-rect-ness for speeding up bounding
boxes and winding numbers. It falls back
to the standard contour code for everything
else.
2023-08-27 09:29:19 -04:00
Matthias Clasen b420540b15 Merge branch 'matthiasc/for-main' into 'main'
Simplify the path spinner demo

See merge request GNOME/gtk!6349
2023-08-27 13:27:50 +00:00
Matthias Clasen 031c0ec3e5 pathpoint: Add some debug API
Add a private gsk_path_point_to_string that
can be called in the debugger if you want
to see the contents of a GskPathPoint and
are too lazy to cast it to GskRealPathPoint
yourself.
2023-08-27 09:14:47 -04:00
Matthias Clasen 43b6822eb0 Add roundtrip tests for special contours
So far, we only have a circle contour.
Check that it survives a roundtrip through
gsk_path_to_string and gsk_path_parse.
2023-08-27 09:14:03 -04:00
Matthias Clasen ba3a657c48 contour: Add some debug API
Add a private  way to get the class of a contour,
so we can test that roundtrips through gsk_path_parse
work as expected.
2023-08-27 09:13:32 -04:00
Matthias Clasen 5f2f116c28 circle contour: Fix a typo 2023-08-27 07:43:55 -04:00
Matthias Clasen 1db75e521d Simplify the path spinner demo
The transforms were obscuring a simple
calculation here.
2023-08-27 07:43:55 -04:00
Matthias Clasen 2297a353b8 Merge branch 'circle-contour' into 'main'
path: Add a circle contour

See merge request GNOME/gtk!6345
2023-08-27 11:12:51 +00:00
Matthias Clasen 80903e5f44 Merge branch 'bilelmoussaoui/gi' into 'main'
gi: Add missing since annotation

See merge request GNOME/gtk!6348
2023-08-27 11:05:31 +00:00
Bilal Elmoussaoui 7342ce5bca gi: Add missing since annotation 2023-08-27 08:17:00 +00:00
Matthias Clasen 167b38dfa1 contour: Some reactoring
Make a default print implementation, and use it.
2023-08-26 23:42:52 -04:00
Matthias Clasen ead88c36ec path: Add circle tests 2023-08-26 23:42:52 -04:00
Matthias Clasen b8a3d7fa00 path: Recognize circles when parsing
We can look out for the tell-tale
M-O-O-O-O-Z and turn it into a circle
contour.
2023-08-26 23:42:52 -04:00
Matthias Clasen 0fce24674a path: Add a circle contour
This special contour takes advantage of the
circle definition to speed up things like
hit testing and closest point determination.
2023-08-26 23:42:52 -04:00
Zander Brown 739084e9bc tooltip: don't cross native boundaries
When walking the tree looking for tooltips we shouldn't cross from, say,
a popover to it's parent window

Fix: https://gitlab.gnome.org/GNOME/gtk/-/issues/1234
Fix: https://gitlab.gnome.org/GNOME/gnome-calendar/-/issues/1038
Fix: https://gitlab.gnome.org/GNOME/gtk/-/issues/5998
Fix: https://gitlab.gnome.org/GNOME/nautilus/-/issues/3063
See: https://gitlab.gnome.org/GNOME/console/-/issues/318
2023-08-27 02:36:51 +01:00
Matthias Clasen 99ad585252 Merge branch 'measure-speedups' into 'main'
contour: Stop doing the roundtrip test

See merge request GNOME/gtk!6342
2023-08-27 01:13:41 +00:00
Matthias Clasen 949b6692ac Merge branch 'matthiasc/for-main' into 'main'
Drop unused code

See merge request GNOME/gtk!6344
2023-08-26 16:46:49 +00:00
Piotr Drąg eb0479d8ed Update POTFILES.in and POTFILES.skip 2023-08-26 17:52:22 +02:00
Matthias Clasen 6defdb4e8a Drop unused code
we are not using any gsk_spline functions currently.
2023-08-26 11:29:09 -04:00
Matthias Clasen 9fdad6d4ee Make randomized path tests less precise
Bump the epsilon in test_split to make these
tests survive longer. They still fail eventually,
unfortunately.
2023-08-26 11:23:02 -04:00
Matthias Clasen b6e285844f Make curve tests pass 2023-08-26 11:22:58 -04:00
Matthias Clasen c989a06718 pathmeasure: compute samples on demand
Only do the work for a curve the first time
we need it. This should greatly speed up
use cases where you only create a measure
to get the length of the path.
2023-08-26 10:23:02 -04:00
Matthias Clasen 1c8bd8658d curve: Cosmetics 2023-08-26 10:23:02 -04:00
Matthias Clasen ab50cba4e9 curve: Reduce the order of our approximation
Use 24 samples instead of 32.
2023-08-26 10:23:02 -04:00
Matthias Clasen 57918813e2 contour: Stop doing the roundtrip test
Doing inverse arclength computations is
a very high overhead operation. And the
tests still pass without it.
2023-08-26 09:39:49 -04:00
Matthias Clasen a4df8d8818 Merge branch 'path-node-tests' into 'main'
css: Replace border rendering code with GskPath

See merge request GNOME/gtk!6341
2023-08-26 12:13:04 +00:00
Matthias Clasen 4b00cfc1ce Merge branch 'macos_ci' into 'main'
Disable macOS CI for forks

See merge request GNOME/gtk!6337
2023-08-26 11:43:57 +00:00
Matthias Clasen 889688c978 Add more fill and stroke node tests 2023-08-26 07:39:23 -04:00
Matthias Clasen 0bf1ae033d Document node format for stroke and fill nodes 2023-08-26 07:39:23 -04:00
Jordi Mas 994afcaeed Update Catalan translation 2023-08-26 09:50:31 +02:00
Matthias Clasen b69cc832ef Merge branch 'path-tool-restrict' into 'main'
path-tool: Add a restrict command

See merge request GNOME/gtk!6340
2023-08-26 04:24:06 +00:00
Matthias Clasen 81c8d1dd28 path-tool: Add length to info output
This requires GskPathMeasure.
2023-08-25 22:26:54 -04:00
Matthias Clasen 32d00ca9ed path-tool: Add a restrict command
This lets you subset a path between two given lengths.
2023-08-25 22:26:54 -04:00
René de Hesselle 2782daadb4 ci: Do not create macOS jobs for forks
The runner is not available in forks (on purpose / for security
reasons), so jobs created there will be stuck indefinitely until they
timeout and fail the pipeline, which is undesireable.

That also means that the initial goal to enable macOS jobs for all MRs
is out of reach: if you are an external contributor (read: non-project
member), your MR pipelines run in your fork, therefore have no access
to the runner.
2023-08-26 01:56:59 +02:00
Lukáš Tyrychtr afbcbb8404 a11y: When a menu item opens a submenu, set its expandable state
To help distinguish submenu opening items, mark them as expandable.
Previously, they only indicated that they had a popup, which is too general.
2023-04-19 11:18:48 +02:00
140 changed files with 27298 additions and 16117 deletions
+1 -3
View File
@@ -207,9 +207,7 @@ msys2-mingw64:
macos-x86_64:
rules:
# run merge request pipelines
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
# do not run in forks
# Do not run in forks as the runner is not available there.
- if: $CI_PROJECT_NAMESPACE == "GNOME"
stage: build
tags:
+6 -9
View File
@@ -35,8 +35,7 @@ The issue tracker is meant to be used for actionable issues only.
You should not open a new issue for security related questions.
When in doubt, send an email to the [security](mailto:security@gnome.org)
mailing list.
When in doubt, follow [security](https://security.gnome.org/).
### Bug reports
@@ -244,13 +243,11 @@ people committing to GTK to follow a few rules:
code, you should always ask. If your change is minor and you've been
working on GTK for a while it probably isn't necessary to ask. But when
in doubt, ask. Even if your change is correct, somebody may know a
better way to do things. If you are making changes to GTK, you should
be subscribed to the [gtk-devel](https://mail.gnome.org/mailman/listinfo/gtk-devel-list)
mailing list; this is a good place to ask about intended changes.
The `#gtk` IRC channel on irc.gnome.org is also a good place to find GTK
developers to discuss changes, but if you live outside of the EU/US time
zones, an email to the gtk-devel mailing list is the most certain and
preferred method.
better way to do things.
The `gtk` [room on matrix](https://matrix.to/#/#gtk:gnome.org) is also a
good place to find GTK developers to discuss changes, but if you live
outside of the EU/US time zones, the [gtk tag on the GNOME Discourse instance](https://discourse.gnome.org/tag/gtk)
is the most certain and preferred method.
0. Ask _first_.
+58
View File
@@ -1,6 +1,64 @@
Overview of Changes in 4.13.1, xx-xx-xxxx
=========================================
* GtkTooltip:
- Don't cross native boundaries when looking for tooltips
* GtkCenterLayout, GtkEntry, GtkSearchEntry:
- Fix some issues with baseline handling
* GtkFileChooser:
- Make "Visit file" scroll to the file
* GtkSwitch:
- Respect text direction
* Paths:
- GskPathMeasure performance has been improved
- Add custom contours for circles, rounded rectangles and rectangles
- Simplify GskPathPoint handling
- gsk_path_point_get_closest_point now returns the distance as well
* Input:
- Handle (some) single-key compose sequences
* GSK:
- Make the repeated gradients match between GL and cairo
- Make rounded rect shrinking match between Vulkan, GL and cairo
- Fix parsing of text nodes with color glyphs
- Restrict an optimization to the cases where it is crrect
- Fix rendering of shadows with opacity
- The Vulkan renderer now requires Vulkan 1.2
* macOS:
- Clamp damage regions to the surface size
* Tools:
- gtk4-path-tool gained restrict and reverse commands
- gtk4-path-tool show and render can show control points
* Demos:
- Add a demo for hit testing with paths
* Build:
- Fix build problems with C++ compilers
* Translation updates
Brazilian Portuguese
British English
Catalan
Czech
Danish
Galician
Georgian
Italian
Korean
Lithuanian
Polish
Punjabi
Slovenian
Overview of Changes in 4.13.0, 25-08-2023
=========================================
+2 -2
View File
@@ -223,7 +223,7 @@ delete_messages (gpointer data)
static void
pop_message (GtkWidget *status)
{
GList *messages = (GList *) g_object_get_data (G_OBJECT (status), "messages");
GList *messages = (GList *) g_object_steal_data (G_OBJECT (status), "messages");
if (messages)
{
@@ -241,7 +241,7 @@ static void
push_message (GtkWidget *status,
const char *message)
{
GList *messages = (GList *) g_object_get_data (G_OBJECT (status), "messages");
GList *messages = (GList *) g_object_steal_data (G_OBJECT (status), "messages");
gtk_label_set_label (GTK_LABEL (status), message);
messages = g_list_prepend (messages, g_strdup (message));
+2
View File
@@ -127,6 +127,7 @@
<file>fishbowl.ui</file>
<file>gtkfishbowl.c</file>
<file>gtkfishbowl.h</file>
<file>tiger.node</file>
</gresource>
<gresource prefix="/frames">
<file>frames.ui</file>
@@ -336,6 +337,7 @@
<file>panes.c</file>
<file>password_entry.c</file>
<file>path_fill.c</file>
<file>path_maze.c</file>
<file>path_spinner.c</file>
<file>path_walk.c</file>
<file>path_text.c</file>
+17
View File
@@ -11,6 +11,9 @@
#include "gtkgears.h"
#include "gskshaderpaintable.h"
#include "nodewidget.h"
#include "graphwidget.h"
const char *const css =
".blurred-button {"
" box-shadow: 0px 0px 5px 10px rgba(0, 0, 0, 0.5);"
@@ -208,6 +211,18 @@ create_menu_button (void)
return w;
}
static GtkWidget *
create_tiger (void)
{
return node_widget_new ("/fishbowl/tiger.node");
}
static GtkWidget *
create_graph (void)
{
return graph_widget_new ();
}
static const struct {
const char *name;
GtkWidget * (*create_func) (void);
@@ -225,6 +240,8 @@ static const struct {
{ "Switch", create_switch },
{ "Menubutton", create_menu_button },
{ "Shader", create_cogs },
{ "Tiger", create_tiger },
{ "Graph", create_graph },
};
static int selected_widget_type = -1;
+153
View File
@@ -0,0 +1,153 @@
#include "graphwidget.h"
struct _GraphWidget
{
GtkWidget parent_instance;
GskPath *path;
GskStroke *stroke;
GdkRGBA color;
guint tick_cb;
guint64 start_time;
double period;
double amplitude;
};
struct _GraphWidgetClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (GraphWidget, graph_widget, GTK_TYPE_WIDGET)
static void
update_path (GraphWidget *self,
float amplitude)
{
graphene_point_t p[20];
GskPathBuilder *builder;
g_clear_pointer (&self->path, gsk_path_unref);
for (int i = 0; i < 20; i++)
{
p[i].x = 10 * i;
p[i].y = 50;
if (i % 4 == 1 || i % 4 == 2)
{
if (i % 8 < 4)
p[i].y += amplitude;
else
p[i].y -= amplitude;
}
}
builder = gsk_path_builder_new ();
gsk_path_builder_move_to (builder, p[0].x, p[0].y);
for (int i = 0; i < 20; i += 4)
gsk_path_builder_cubic_to (builder,
p[i+1].x, p[i+1].y,
p[i+2].x, p[i+2].y,
p[i+3].x, p[i+3].y);
self->path = gsk_path_builder_free_to_path (builder);
}
static gboolean
tick_cb (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer user_data)
{
GraphWidget *self = GRAPH_WIDGET (widget);
guint64 now;
double angle;
now = gdk_frame_clock_get_frame_time (frame_clock);
if (self->start_time == 0)
self->start_time = now;
angle = 360 * (now - self->start_time) / (double)(self->period * G_TIME_SPAN_MINUTE);
update_path (self, sin (angle) * self->amplitude);
gtk_widget_queue_draw (widget);
return G_SOURCE_CONTINUE;
}
static void
graph_widget_init (GraphWidget *self)
{
self->color.red = g_random_double_range (0, 1);
self->color.green = g_random_double_range (0, 1);
self->color.blue = g_random_double_range (0, 1);
self->color.alpha = 1;
self->period = g_random_double_range (0.5, 1);
self->amplitude = g_random_double_range (10, 25);
self->stroke = gsk_stroke_new (2);
update_path (self, 0);
self->start_time = 0;
self->tick_cb = gtk_widget_add_tick_callback (GTK_WIDGET (self), tick_cb, NULL, NULL);
}
static void
graph_widget_dispose (GObject *object)
{
GraphWidget *self = GRAPH_WIDGET (object);
g_clear_pointer (&self->path, gsk_path_unref);
gsk_stroke_free (self->stroke);
G_OBJECT_CLASS (graph_widget_parent_class)->dispose (object);
}
static void
graph_widget_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GraphWidget *self = GRAPH_WIDGET (widget);
gtk_snapshot_append_stroke (snapshot, self->path, self->stroke, &self->color);
}
static void
graph_widget_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
if (orientation == GTK_ORIENTATION_HORIZONTAL)
*minimum = *natural = 200;
else
*minimum = *natural = 100;
}
static void
graph_widget_class_init (GraphWidgetClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->dispose = graph_widget_dispose;
widget_class->snapshot = graph_widget_snapshot;
widget_class->measure = graph_widget_measure;
}
GtkWidget *
graph_widget_new (void)
{
return g_object_new (GRAPH_TYPE_WIDGET, NULL);
}
+8
View File
@@ -0,0 +1,8 @@
#pragma once
#include <gtk/gtk.h>
#define GRAPH_TYPE_WIDGET (graph_widget_get_type ())
G_DECLARE_FINAL_TYPE (GraphWidget, graph_widget, GRAPH, WIDGET, GtkWidget)
GtkWidget * graph_widget_new (void);
+3
View File
@@ -73,6 +73,7 @@ demos = files([
'panes.c',
'password_entry.c',
'path_fill.c',
'path_maze.c',
'path_spinner.c',
'path_walk.c',
'path_text.c',
@@ -140,6 +141,8 @@ extra_demo_sources = files([
'unicode-names.c',
'suggestionentry.c',
'language-names.c',
'nodewidget.c',
'graphwidget.c',
])
if os_unix
+76
View File
@@ -0,0 +1,76 @@
#include "nodewidget.h"
struct _NodeWidget
{
GtkWidget parent_instance;
GskRenderNode *node;
};
struct _NodeWidgetClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (NodeWidget, node_widget, GTK_TYPE_WIDGET)
static void
node_widget_init (NodeWidget *self)
{
}
static void
node_widget_dispose (GObject *object)
{
NodeWidget *self = NODE_WIDGET (object);
gsk_render_node_unref (self->node);
G_OBJECT_CLASS (node_widget_parent_class)->dispose (object);
}
static void
node_widget_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
NodeWidget *self = NODE_WIDGET (widget);
gtk_snapshot_append_node (snapshot, self->node);
}
static void
node_widget_class_init (NodeWidgetClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->dispose = node_widget_dispose;
widget_class->snapshot = node_widget_snapshot;
}
GtkWidget *
node_widget_new (const char *resource)
{
NodeWidget *self;
GBytes *bytes;
GskRenderNode *node;
graphene_rect_t bounds;
float scale;
GskTransform *transform;
self = g_object_new (NODE_TYPE_WIDGET, NULL);
bytes = g_resources_lookup_data (resource, 0, NULL);
node = gsk_render_node_deserialize (bytes, NULL, NULL);
g_bytes_unref (bytes);
gsk_render_node_get_bounds (node, &bounds);
scale = MIN (100.0/bounds.size.width, 100.0/bounds.size.height);
transform = gsk_transform_scale (NULL, scale, scale);
self->node = gsk_transform_node_new (node, transform);
gsk_transform_unref (transform);
gsk_render_node_unref (node);
return GTK_WIDGET (self);
}
+8
View File
@@ -0,0 +1,8 @@
#pragma once
#include <gtk/gtk.h>
#define NODE_TYPE_WIDGET (node_widget_get_type ())
G_DECLARE_FINAL_TYPE (NodeWidget, node_widget, NODE, WIDGET, GtkWidget)
GtkWidget * node_widget_new (const char *file);
+369
View File
@@ -0,0 +1,369 @@
/* Path/Maze
*
* This demo shows how to use a GskPath to create a maze and use
* gsk_path_get_closest_point() to check the mouse stays
* on the path.
*
* It also shows off the performance of GskPath (or not) as this
* is a rather complex path.
*/
#include "config.h"
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "paintable.h"
#define MAZE_GRID_SIZE 20
#define MAZE_STROKE_SIZE_ACTIVE (MAZE_GRID_SIZE - 4)
#define MAZE_STROKE_SIZE_INACTIVE (MAZE_GRID_SIZE - 12)
#define MAZE_WIDTH 31
#define MAZE_HEIGHT 21
#define GTK_TYPE_MAZE (gtk_maze_get_type ())
G_DECLARE_FINAL_TYPE (GtkMaze, gtk_maze, GTK, MAZE, GtkWidget)
struct _GtkMaze
{
GtkWidget parent_instance;
int width;
int height;
GskPath *path;
GskPathMeasure *measure;
GdkPaintable *background;
gboolean active;
};
struct _GtkMazeClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (GtkMaze, gtk_maze, GTK_TYPE_WIDGET)
static void
gtk_maze_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
GtkMaze *self = GTK_MAZE (widget);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
*minimum = *natural = self->width;
else
*minimum = *natural = self->height;
}
static void
gtk_maze_snapshot (GtkWidget *widget,
GdkSnapshot *snapshot)
{
GtkMaze *self = GTK_MAZE (widget);
double width = gtk_widget_get_width (widget);
double height = gtk_widget_get_height (widget);
GskStroke *stroke;
stroke = gsk_stroke_new (MAZE_STROKE_SIZE_INACTIVE);
if (self->active)
gsk_stroke_set_line_width (stroke, MAZE_STROKE_SIZE_ACTIVE);
gsk_stroke_set_line_join (stroke, GSK_LINE_JOIN_ROUND);
gsk_stroke_set_line_cap (stroke, GSK_LINE_CAP_ROUND);
gtk_snapshot_push_stroke (snapshot, self->path, stroke);
gsk_stroke_free (stroke);
if (self->background)
{
gdk_paintable_snapshot (self->background, snapshot, width, height);
}
else
{
gtk_snapshot_append_linear_gradient (snapshot,
&GRAPHENE_RECT_INIT (0, 0, width, height),
&GRAPHENE_POINT_INIT (0, 0),
&GRAPHENE_POINT_INIT (width, height),
(GskColorStop[8]) {
{ 0.0, { 1.0, 0.0, 0.0, 1.0 } },
{ 0.2, { 1.0, 0.0, 0.0, 1.0 } },
{ 0.3, { 1.0, 1.0, 0.0, 1.0 } },
{ 0.4, { 0.0, 1.0, 0.0, 1.0 } },
{ 0.6, { 0.0, 1.0, 1.0, 1.0 } },
{ 0.7, { 0.0, 0.0, 1.0, 1.0 } },
{ 0.8, { 1.0, 0.0, 1.0, 1.0 } },
{ 1.0, { 1.0, 0.0, 1.0, 1.0 } }
},
8);
}
gtk_snapshot_pop (snapshot);
}
static void
gtk_maze_dispose (GObject *object)
{
GtkMaze *self = GTK_MAZE (object);
g_clear_pointer (&self->path, gsk_path_unref);
g_clear_pointer (&self->measure, gsk_path_measure_unref);
if (self->background)
{
g_signal_handlers_disconnect_matched (self->background, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
g_clear_object (&self->background);
}
G_OBJECT_CLASS (gtk_maze_parent_class)->dispose (object);
}
static void
gtk_maze_class_init (GtkMazeClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gtk_maze_dispose;
widget_class->measure = gtk_maze_measure;
widget_class->snapshot = gtk_maze_snapshot;
}
static void
celebrate (gboolean win)
{
char *path;
GtkMediaStream *stream;
if (win)
path = g_build_filename (GTK_DATADIR, "sounds", "freedesktop", "stereo", "complete.oga", NULL);
else
path = g_build_filename (GTK_DATADIR, "sounds", "freedesktop", "stereo", "suspend-error.oga", NULL);
stream = gtk_media_file_new_for_filename (path);
gtk_media_stream_set_volume (stream, 1.0);
gtk_media_stream_play (stream);
g_signal_connect (stream, "notify::ended", G_CALLBACK (g_object_unref), NULL);
g_free (path);
}
static void
pointer_motion (GtkEventControllerMotion *controller,
double x,
double y,
GtkMaze *self)
{
GskPathPoint point;
float distance;
if (!self->active)
return;
if (gsk_path_get_closest_point (self->path,
&GRAPHENE_POINT_INIT (x, y),
INFINITY,
&point,
&distance))
{
if (distance < MAZE_STROKE_SIZE_ACTIVE / 2.f)
return;
}
celebrate (FALSE);
self->active = FALSE;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
pointer_leave (GtkEventControllerMotion *controller,
GtkMaze *self)
{
if (!self->active)
{
self->active = TRUE;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
}
static void
gtk_maze_init (GtkMaze *self)
{
GtkEventController *controller;
controller = GTK_EVENT_CONTROLLER (gtk_event_controller_motion_new ());
g_signal_connect (controller, "motion", G_CALLBACK (pointer_motion), self);
g_signal_connect (controller, "leave", G_CALLBACK (pointer_leave), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
self->active = TRUE;
}
static void
gtk_maze_set_path (GtkMaze *self,
GskPath *path)
{
g_clear_pointer (&self->path, gsk_path_unref);
g_clear_pointer (&self->measure, gsk_path_measure_unref);
self->path = gsk_path_ref (path);
self->measure = gsk_path_measure_new (path);
gtk_widget_queue_draw (GTK_WIDGET (self));
}
GtkWidget *
gtk_maze_new (GskPath *path,
GdkPaintable *background,
int width,
int height)
{
GtkMaze *self;
self = g_object_new (GTK_TYPE_MAZE, NULL);
gtk_maze_set_path (self, path);
gsk_path_unref (path);
self->background = background;
if (self->background)
{
g_signal_connect_swapped (self->background, "invalidate-contents", G_CALLBACK (gtk_widget_queue_draw), self);
g_signal_connect_swapped (self->background, "invalidate-size", G_CALLBACK (gtk_widget_queue_resize), self);
}
self->width = width;
self->height = height;
return GTK_WIDGET (self);
}
static void
add_point_to_maze (GtkBitset *maze,
GskPathBuilder *builder,
guint x,
guint y)
{
gboolean set[4] = { FALSE, FALSE, FALSE, FALSE };
guint dir;
gtk_bitset_add (maze, y * MAZE_WIDTH + x);
while (TRUE)
{
set[0] = set[0] || x == 0 || gtk_bitset_contains (maze, y * MAZE_WIDTH + x - 1);
set[1] = set[1] || y == 0 || gtk_bitset_contains (maze, (y - 1) * MAZE_WIDTH + x);
set[2] = set[2] || x + 1 == MAZE_WIDTH || gtk_bitset_contains (maze, y * MAZE_WIDTH + x + 1);
set[3] = set[3] || y + 1 == MAZE_HEIGHT || gtk_bitset_contains (maze, (y + 1) * MAZE_WIDTH + x);
if (set[0] && set[1] && set[2] && set[3])
return;
do
{
dir = g_random_int_range (0, 4);
}
while (set[dir]);
switch (dir)
{
case 0:
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, (x - 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
add_point_to_maze (maze, builder, x - 1, y);
break;
case 1:
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y - 0.5) * MAZE_GRID_SIZE);
add_point_to_maze (maze, builder, x, y - 1);
break;
case 2:
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, (x + 1.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
add_point_to_maze (maze, builder, x + 1, y);
break;
case 3:
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 1.5) * MAZE_GRID_SIZE);
add_point_to_maze (maze, builder, x, y + 1);
break;
default:
g_assert_not_reached ();
break;
}
}
}
static GskPath *
create_path_for_maze (GtkWidget *widget)
{
GskPathBuilder *builder;
GtkBitset *maze;
builder = gsk_path_builder_new ();
maze = gtk_bitset_new_empty ();
/* make sure the outer lines are unreachable:
* Set the full range, then remove the center again. */
gtk_bitset_add_range (maze, 0, MAZE_WIDTH * MAZE_HEIGHT);
gtk_bitset_remove_rectangle (maze, MAZE_WIDTH + 1, MAZE_WIDTH - 2, MAZE_HEIGHT - 2, MAZE_WIDTH);
/* Fill the maze */
add_point_to_maze (maze, builder, MAZE_WIDTH / 2, MAZE_HEIGHT / 2);
/* Add start and stop lines */
gsk_path_builder_move_to (builder, 1.5 * MAZE_GRID_SIZE, -0.5 * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, 1.5 * MAZE_GRID_SIZE, 1.5 * MAZE_GRID_SIZE);
gsk_path_builder_move_to (builder, (MAZE_WIDTH - 1.5) * MAZE_GRID_SIZE, (MAZE_HEIGHT - 1.5) * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, (MAZE_WIDTH - 1.5) * MAZE_GRID_SIZE, (MAZE_HEIGHT + 0.5) * MAZE_GRID_SIZE);
gtk_bitset_unref (maze);
return gsk_path_builder_free_to_path (builder);
}
GtkWidget *
do_path_maze (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkWidget *maze;
GtkMediaStream *stream;
GskPath *path;
window = gtk_window_new ();
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
gtk_window_set_title (GTK_WINDOW (window), "Follow the maze with the mouse");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
#if 0
stream = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
#else
stream = gtk_nuclear_media_stream_new ();
#endif
gtk_media_stream_play (stream);
gtk_media_stream_set_loop (stream, TRUE);
path = create_path_for_maze (window);
maze = gtk_maze_new (path,
GDK_PAINTABLE (stream),
MAZE_WIDTH * MAZE_GRID_SIZE,
MAZE_HEIGHT * MAZE_GRID_SIZE);
gtk_window_set_child (GTK_WINDOW (window), maze);
}
if (!gtk_widget_get_visible (window))
gtk_window_present (GTK_WINDOW (window));
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}
+10 -21
View File
@@ -56,9 +56,9 @@ gtk_spinner_paintable_get_intrinsic_height (GdkPaintable *paintable)
static void
gtk_spinner_paintable_snapshot (GdkPaintable *paintable,
GdkSnapshot *snapshot,
double width,
double height)
GdkSnapshot *snapshot,
double width,
double height)
{
GtkSpinnerPaintable *self = GTK_SPINNER_PAINTABLE (paintable);
@@ -190,32 +190,21 @@ update_path (GtkSpinnerPaintable *self)
{
GskPathBuilder *builder;
GskPathPoint start, end;
GskTransform *t;
graphene_point_t p, p0, p1;
graphene_point_t p0, p1;
float start_angle, end_angle;
p = GRAPHENE_POINT_INIT (40, 0);
start_angle = self->angle;
end_angle = fmod (self->angle + 360 * self->completion / 100, 360);
t = gsk_transform_translate (
gsk_transform_rotate (
gsk_transform_translate (NULL, &GRAPHENE_POINT_INIT (50, 50)),
start_angle),
&GRAPHENE_POINT_INIT (-50, -50));
gsk_transform_transform_point (t, &p, &p0);
t = gsk_transform_translate (
gsk_transform_rotate (
gsk_transform_translate (NULL, &GRAPHENE_POINT_INIT (50, 50)),
end_angle),
&GRAPHENE_POINT_INIT (-50, -50));
gsk_transform_transform_point (t, &p, &p1);
p0 = GRAPHENE_POINT_INIT (50 + 40 * cos (M_PI * start_angle / 180),
50 + 40 * sin (M_PI * start_angle / 180));
p1 = GRAPHENE_POINT_INIT (50 + 40 * cos (M_PI * end_angle / 180),
50 + 40 * sin (M_PI * end_angle / 180));
g_clear_pointer (&self->path, gsk_path_unref);
gsk_path_get_closest_point (self->circle, &p0, INFINITY, &start);
gsk_path_get_closest_point (self->circle, &p1, INFINITY, &end);
gsk_path_get_closest_point (self->circle, &p0, INFINITY, &start, NULL);
gsk_path_get_closest_point (self->circle, &p1, INFINITY, &end, NULL);
builder = gsk_path_builder_new ();
gsk_path_builder_add_segment (builder, self->circle, &start, &end);
+2 -4
View File
@@ -501,15 +501,13 @@ pointer_motion (GtkEventControllerMotion *controller,
GtkPathWidget *self)
{
GskPathPoint point;
graphene_point_t pos;
if (gsk_path_get_closest_point (self->line_path,
&GRAPHENE_POINT_INIT (x, y),
INFINITY,
&point))
&point,
NULL))
{
gsk_path_point_get_position (&point, self->line_path, &pos);
gtk_widget_queue_draw (GTK_WIDGET (self));
}
}
+2
View File
@@ -11,6 +11,8 @@
<property name="lower">0</property>
<property name="upper">5000</property>
<property name="value">500</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
</object>
</property>
</object>
File diff suppressed because it is too large Load Diff
+9 -7
View File
@@ -149,15 +149,16 @@ Creates a node like `gsk_debug_node_new()` with the given properties.
### fill
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| child | `<node>` | *see below* | always |
| path | `<string>` | "" | always |
| fill-rule| `<fill-rule>` | winding | always |
| property | syntax | default | printed |
| --------- | --------------- | ---------------------- | ----------- |
| child | `<node>` | *see below* | always |
| path | `<string>` | "" | always |
| fill-rule | `<fill-rule>` | winding | always |
Creates a node like `gsk_fill_node_new()` with the given properties.
The default child node is created with the bounds of the path.
The default child node is the default color node, but created with the
bounds of the path.
### glshader
@@ -316,7 +317,8 @@ Creates a node like `gsk_shadow_node_new()` with the given properties.
Creates a node like `gsk_stroke_node_new()` with the given properties.
The default child node is created with the stroke bounds of the path.
The default child node is the default color node, but created with the
stroke bounds of the path.
### text
+47 -14
View File
@@ -15,6 +15,7 @@ SYNOPSIS
| **gtk4-path-tool** decompose [OPTIONS...] <PATH>
| **gtk4-path-tool** show [OPTIONS...] <PATH>
| **gtk4-path-tool** render [OPTIONS...] <PATH>
| **gtk4-path-tool** reverse [OPTIONS...] <PATH>
| **gtk4-path-tool** info [OPTIONS...] <PATH>
DESCRIPTION
@@ -54,6 +55,22 @@ Showing
The ``show`` command displays the given path in a window. The interior
of the path is filled.
``--fill``
Fill the path (this is the default).
``--stroke``
Stroke the path instead of filling it.
``--points``
Show points on the path.
``--controls``
Show control points.
``--fill-rule=VALUE``
The fill rule that is used to determine what areas are inside the path.
@@ -69,13 +86,10 @@ of the path is filled.
The color that is used to render the background behind the path.
If not specified, white is used.
``--fill``
``--point-color=COLOR``
Fill the path (this is the default).
``--stroke``
Stroke the path instead of filling it.
The color that is used to render the points.
If not specified, red is used.
``--line-width=VALUE``
@@ -118,6 +132,22 @@ Rendering
The ``render`` command renders the given path as a PNG image.
The interior of the path is filled.
``--fill``
Fill the path (this is the default).
``--stroke``
Stroke the path instead of filling it.
``--points``
Show points on the path.
``--controls``
Show control points.
``--fill-rule=VALUE``
The fill rule that is used to determine what areas are inside the path.
@@ -133,19 +163,16 @@ The interior of the path is filled.
The color that is used to render the background behind the path.
If not specified, white is used.
``--point-color=COLOR``
The color that is used to render the points.
If not specified, red is used.
``--output-file=FILE``
The file to save the PNG image to.
If not specified, "path.png" is used.
``--fill``
Fill the path (this is the default).
``--stroke``
Stroke the path instead of filling it.
``--line-width=VALUE``
The line width to use for the stroke. ``VALUE`` must be a positive number.
@@ -181,6 +208,12 @@ The interior of the path is filled.
The offset into the dash pattern where dashing should begin.
The default value is 0.
Reversing
^^^^^^^^^
The ``reverse`` command changes the direction of the path. The resulting
paths starts where the original path ends.
Info
^^^^
+44 -12
View File
@@ -82,6 +82,18 @@ gdk_array(init) (GdkArray *self)
#endif
}
G_GNUC_UNUSED static inline gsize
gdk_array(get_capacity) (const GdkArray *self)
{
return self->end_allocation - self->start;
}
G_GNUC_UNUSED static inline gsize
gdk_array(get_size) (const GdkArray *self)
{
return self->end - self->start;
}
static inline void
gdk_array(free_elements) (_T_ *start,
_T_ *end)
@@ -110,6 +122,38 @@ gdk_array(clear) (GdkArray *self)
gdk_array(init) (self);
}
/*
* gdk_array_steal:
* @self: the array
*
* Steals all data in the array and clears the array.
*
* If you need to know the size of the data, you should query it
* beforehand.
*
* Returns: The array's data
**/
G_GNUC_UNUSED static inline _T_ *
gdk_array(steal) (GdkArray *self)
{
_T_ *result;
#ifdef GDK_ARRAY_PREALLOC
if (self->start == self->preallocated)
{
gsize size = GDK_ARRAY_REAL_SIZE (gdk_array(get_size) (self));
result = g_new (_T_, size);
memcpy (result, self->preallocated, sizeof (_T_) * size);
}
else
#endif
result = self->start;
gdk_array(init) (self);
return result;
}
G_GNUC_UNUSED static inline _T_ *
gdk_array(get_data) (const GdkArray *self)
{
@@ -123,18 +167,6 @@ gdk_array(index) (const GdkArray *self,
return self->start + pos;
}
G_GNUC_UNUSED static inline gsize
gdk_array(get_capacity) (const GdkArray *self)
{
return self->end_allocation - self->start;
}
G_GNUC_UNUSED static inline gsize
gdk_array(get_size) (const GdkArray *self)
{
return self->end - self->start;
}
G_GNUC_UNUSED static inline gboolean
gdk_array(is_empty) (const GdkArray *self)
{
+1 -2
View File
@@ -473,8 +473,7 @@ gdk_display_get_event (GdkDisplay *display)
* @display: a `GdkDisplay`
* @event: (transfer none): a `GdkEvent`
*
* Appends the given event onto the front of the event
* queue for @display.
* Adds the given event to the event queue for @display.
*
* Deprecated: 4.10: This function is only useful in very
* special situations and should not be used by applications.
+6 -3
View File
@@ -1408,8 +1408,11 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
},
.enabledExtensionCount = device_extensions->len,
.ppEnabledExtensionNames = (const char * const *) device_extensions->pdata,
.pNext = &(VkPhysicalDeviceDescriptorIndexingFeatures) {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES,
.pNext = &(VkPhysicalDeviceVulkan12Features) {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
.shaderSampledImageArrayNonUniformIndexing = VK_TRUE,
.shaderStorageBufferArrayNonUniformIndexing = VK_TRUE,
.descriptorIndexing = VK_TRUE,
.descriptorBindingPartiallyBound = VK_TRUE,
.descriptorBindingVariableDescriptorCount = VK_TRUE,
.descriptorBindingSampledImageUpdateAfterBind = VK_TRUE,
@@ -1553,7 +1556,7 @@ gdk_display_create_vulkan_instance (GdkDisplay *display,
.applicationVersion = 0,
.pEngineName = "GTK",
.engineVersion = VK_MAKE_VERSION (GDK_MAJOR_VERSION, GDK_MINOR_VERSION, GDK_MICRO_VERSION),
.apiVersion = VK_API_VERSION_1_0
.apiVersion = VK_API_VERSION_1_2
},
.enabledLayerCount = used_layers->len,
.ppEnabledLayerNames = (const char * const *) used_layers->pdata,
+10
View File
@@ -188,6 +188,14 @@ copy_surface_data (GdkMacosBuffer *from,
}
}
static void
clamp_region_to_surface (cairo_region_t *region,
GdkSurface *surface)
{
cairo_rectangle_int_t rectangle = {0, 0, surface->width, surface->height};
cairo_region_intersect_rectangle (region, &rectangle);
}
static void
_gdk_macos_cairo_context_begin_frame (GdkDrawContext *draw_context,
GdkMemoryDepth depth,
@@ -205,6 +213,8 @@ _gdk_macos_cairo_context_begin_frame (GdkDrawContext *draw_context,
surface = GDK_MACOS_SURFACE (gdk_draw_context_get_surface (draw_context));
buffer = _gdk_macos_surface_get_buffer (surface);
clamp_region_to_surface (region, GDK_SURFACE (surface));
_gdk_macos_buffer_set_damage (buffer, region);
_gdk_macos_buffer_set_flipped (buffer, FALSE);
+1 -1
View File
@@ -90,7 +90,7 @@ struct _GdkMacosDisplay
/* Note if we have a key window that is not a GdkMacosWindow
* such as a NSPanel used for native dialogs.
*/
guint key_window_is_foregin : 1;
guint key_window_is_foreign : 1;
};
struct _GdkMacosDisplayClass
+3 -3
View File
@@ -424,7 +424,7 @@ select_key_in_idle_cb (gpointer data)
self->select_key_in_idle = 0;
/* Don't steal focus from NSPanel, etc */
if (self->key_window_is_foregin)
if (self->key_window_is_foreign)
return G_SOURCE_REMOVE;
if (self->keyboard_surface == NULL)
@@ -941,7 +941,7 @@ _gdk_macos_display_get_surfaces (GdkMacosDisplay *self)
NSArray *array = [NSApp orderedWindows];
GQueue sorted = G_QUEUE_INIT;
self->key_window_is_foregin = FALSE;
self->key_window_is_foreign = FALSE;
for (id obj in array)
{
@@ -949,7 +949,7 @@ _gdk_macos_display_get_surfaces (GdkMacosDisplay *self)
GdkMacosSurface *surface;
if ([nswindow isKeyWindow])
self->key_window_is_foregin = !GDK_IS_MACOS_WINDOW (nswindow);
self->key_window_is_foreign = !GDK_IS_MACOS_WINDOW (nswindow);
if (!GDK_IS_MACOS_WINDOW (nswindow))
continue;
+16 -4
View File
@@ -46,6 +46,21 @@ static const struct xdg_activation_token_v1_listener token_listener = {
token_done,
};
static struct wl_surface *
peek_launcher_toplevel (GdkSeat *seat)
{
struct wl_surface *wl_surface = NULL;
GdkSurface *focus_surface;
focus_surface = gdk_wayland_device_get_focus (gdk_seat_get_keyboard (seat));
while (focus_surface && focus_surface->parent)
focus_surface = focus_surface->parent;
if (focus_surface)
wl_surface = gdk_wayland_surface_get_wl_surface (focus_surface);
return wl_surface;
}
static char *
gdk_wayland_app_launch_context_get_startup_notify_id (GAppLaunchContext *context,
GAppInfo *info,
@@ -62,7 +77,6 @@ gdk_wayland_app_launch_context_get_startup_notify_id (GAppLaunchContext *context
struct wl_event_queue *event_queue;
struct wl_surface *wl_surface = NULL;
GdkWaylandSeat *seat;
GdkSurface *focus_surface;
AppLaunchData app_launch_data = { 0 };
event_queue = wl_display_create_queue (display->wl_display);
@@ -78,9 +92,7 @@ gdk_wayland_app_launch_context_get_startup_notify_id (GAppLaunchContext *context
_gdk_wayland_seat_get_last_implicit_grab_serial (seat, NULL),
gdk_wayland_seat_get_wl_seat (GDK_SEAT (seat)));
focus_surface = gdk_wayland_device_get_focus (gdk_seat_get_keyboard (GDK_SEAT (seat)));
if (focus_surface)
wl_surface = gdk_wayland_surface_get_wl_surface (focus_surface);
wl_surface = peek_launcher_toplevel (GDK_SEAT (seat));
if (wl_surface)
xdg_activation_token_v1_set_surface (token, wl_surface);
+8 -1
View File
@@ -96,6 +96,12 @@
#define XDG_ACTIVATION_VERSION 1
#define OUTPUT_VERSION 3
#ifdef HAVE_TOPLEVEL_STATE_SUSPENDED
#define XDG_WM_BASE_VERSION 6
#else
#define XDG_WM_BASE_VERSION 5
#endif
static void _gdk_wayland_display_load_cursor_theme (GdkWaylandDisplay *display_wayland);
G_DEFINE_TYPE (GdkWaylandDisplay, gdk_wayland_display, GDK_TYPE_DISPLAY)
@@ -638,7 +644,8 @@ _gdk_wayland_display_open (const char *display_name)
wl_registry_bind (display_wayland->wl_registry,
display_wayland->xdg_wm_base_id,
&xdg_wm_base_interface,
MIN (display_wayland->xdg_wm_base_version, 4));
MIN (display_wayland->xdg_wm_base_version,
XDG_WM_BASE_VERSION));
xdg_wm_base_add_listener (display_wayland->xdg_wm_base,
&xdg_wm_base_listener,
display_wayland);
+8
View File
@@ -672,10 +672,18 @@ xdg_toplevel_configure_bounds (void *data,
toplevel->pending.has_bounds = TRUE;
}
static void
xdg_toplevel_wm_capabilities (void *data,
struct xdg_toplevel *xdg_toplevel,
struct wl_array *capabilities)
{
}
static const struct xdg_toplevel_listener xdg_toplevel_listener = {
xdg_toplevel_configure,
xdg_toplevel_close,
xdg_toplevel_configure_bounds,
xdg_toplevel_wm_capabilities,
};
static void
+1 -1
View File
@@ -20,7 +20,7 @@
#pragma once
#include <gsk/gskrenderer.h>
#include <gsk/gsk.h>
G_BEGIN_DECLS
+30 -5
View File
@@ -142,6 +142,8 @@ struct _GskGLRenderJob
const GskGLRenderModelview *current_modelview;
GskGLProgram *current_program;
guint source_is_glyph_atlas : 1;
/* If we should be rendering red zones over fallback nodes */
guint debug_fallback : 1;
@@ -1260,6 +1262,7 @@ done:
GL_TEXTURE_2D,
GL_TEXTURE0,
texture_id);
job->source_is_glyph_atlas = FALSE;
gsk_gl_render_job_draw_offscreen_rect (job, &node->bounds);
gsk_gl_render_job_end_draw (job);
@@ -1325,6 +1328,7 @@ blur_offscreen (GskGLRenderJob *job,
GL_TEXTURE_2D,
GL_TEXTURE0,
offscreen->texture_id);
job->source_is_glyph_atlas = FALSE;
gsk_gl_program_set_uniform1f (job->current_program,
UNIFORM_BLUR_RADIUS, 0,
blur_radius_x);
@@ -1354,6 +1358,7 @@ blur_offscreen (GskGLRenderJob *job,
GL_TEXTURE_2D,
GL_TEXTURE0,
pass1->texture_id);
job->source_is_glyph_atlas = FALSE;
gsk_gl_program_set_uniform1f (job->current_program,
UNIFORM_BLUR_RADIUS, 0,
blur_radius_y);
@@ -1461,7 +1466,8 @@ gsk_gl_render_job_visit_color_node (GskGLRenderJob *job,
batch = gsk_gl_command_queue_get_batch (job->command_queue);
/* Limit the size, or we end up with a coordinate overflow somewhere. */
if (node->bounds.size.width < 300 &&
if (job->source_is_glyph_atlas &&
node->bounds.size.width < 300 &&
node->bounds.size.height < 300 &&
batch->any.kind == GSK_GL_COMMAND_KIND_DRAW &&
batch->any.program == program->id)
@@ -1668,6 +1674,7 @@ gsk_gl_render_job_visit_clipped_child (GskGLRenderJob *job,
GL_TEXTURE_2D,
GL_TEXTURE0,
offscreen.texture_id);
job->source_is_glyph_atlas = FALSE;
gsk_gl_render_job_draw_offscreen_rect (job, clip);
gsk_gl_render_job_end_draw (job);
}
@@ -1758,6 +1765,7 @@ gsk_gl_render_job_visit_rounded_clip_node (GskGLRenderJob *job,
GL_TEXTURE_2D,
GL_TEXTURE0,
offscreen.texture_id);
job->source_is_glyph_atlas = FALSE;
gsk_gl_render_job_draw_offscreen (job, &node->bounds, &offscreen);
gsk_gl_render_job_end_draw (job);
}
@@ -2123,6 +2131,7 @@ gsk_gl_render_job_visit_transform_node (GskGLRenderJob *job,
offscreen.texture_id,
linear_filter ? GL_LINEAR : GL_NEAREST,
linear_filter ? GL_LINEAR : GL_NEAREST);
job->source_is_glyph_atlas = FALSE;
gsk_gl_render_job_draw_offscreen (job, &child->bounds, &offscreen);
gsk_gl_render_job_end_draw (job);
}
@@ -2332,6 +2341,7 @@ gsk_gl_render_job_visit_blurred_inset_shadow_node (GskGLRenderJob *job,
GL_TEXTURE_2D,
GL_TEXTURE0,
blurred_texture_id);
job->source_is_glyph_atlas = FALSE;
gsk_gl_render_job_draw_offscreen (job, &node->bounds, &offscreen);
gsk_gl_render_job_end_draw (job);
}
@@ -2597,6 +2607,7 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job,
GL_TEXTURE_2D,
GL_TEXTURE0,
blurred_texture_id);
job->source_is_glyph_atlas = FALSE;
gsk_gl_program_set_uniform_rounded_rect (job->current_program,
UNIFORM_OUTSET_SHADOW_OUTLINE_RECT, 0,
&transformed_outline);
@@ -2622,6 +2633,7 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job,
GL_TEXTURE_2D,
GL_TEXTURE0,
blurred_texture_id);
job->source_is_glyph_atlas = FALSE;
gsk_gl_program_set_uniform_rounded_rect (job->current_program,
UNIFORM_OUTSET_SHADOW_OUTLINE_RECT, 0,
&transformed_outline);
@@ -2859,6 +2871,7 @@ gsk_gl_render_job_visit_cross_fade_node (GskGLRenderJob *job,
GL_TEXTURE_2D,
GL_TEXTURE1,
offscreen_end.texture_id);
job->source_is_glyph_atlas = FALSE;
gsk_gl_program_set_uniform1f (job->current_program,
UNIFORM_CROSS_FADE_PROGRESS, 0,
progress);
@@ -2905,6 +2918,7 @@ gsk_gl_render_job_visit_opacity_node (GskGLRenderJob *job,
GL_TEXTURE_2D,
GL_TEXTURE0,
offscreen.texture_id);
job->source_is_glyph_atlas = FALSE;
gsk_gl_render_job_draw_offscreen (job, &node->bounds, &offscreen);
gsk_gl_render_job_end_draw (job);
}
@@ -3046,6 +3060,7 @@ gsk_gl_render_job_visit_text_node (GskGLRenderJob *job,
GL_TEXTURE_2D,
GL_TEXTURE0,
texture_id);
job->source_is_glyph_atlas = TRUE;
last_texture = texture_id;
}
@@ -3142,10 +3157,6 @@ gsk_gl_render_job_visit_shadow_node (GskGLRenderJob *job,
offscreen.was_offscreen = TRUE;
}
else if (dx == 0 && dy == 0)
{
continue; /* Invisible anyway */
}
else
{
offscreen.bounds = &shadow_child->bounds;
@@ -3166,6 +3177,7 @@ gsk_gl_render_job_visit_shadow_node (GskGLRenderJob *job,
GL_TEXTURE_2D,
GL_TEXTURE0,
offscreen.texture_id);
job->source_is_glyph_atlas = FALSE;
rgba_to_half (&shadow->color, color);
gsk_gl_render_job_draw_offscreen_with_color (job, &bounds, &offscreen, color);
gsk_gl_render_job_end_draw (job);
@@ -3222,6 +3234,7 @@ gsk_gl_render_job_visit_blur_node (GskGLRenderJob *job,
GL_TEXTURE_2D,
GL_TEXTURE0,
offscreen.texture_id);
job->source_is_glyph_atlas = FALSE;
gsk_gl_render_job_draw_coords (job,
min_x, min_y, max_x, max_y,
0, 1, 1, 0,
@@ -3272,6 +3285,7 @@ gsk_gl_render_job_visit_blend_node (GskGLRenderJob *job,
GL_TEXTURE_2D,
GL_TEXTURE0,
bottom_offscreen.texture_id);
job->source_is_glyph_atlas = FALSE;
gsk_gl_render_job_draw_offscreen (job, &node->bounds, &bottom_offscreen);
gsk_gl_render_job_end_draw (job);
}
@@ -3294,6 +3308,7 @@ gsk_gl_render_job_visit_blend_node (GskGLRenderJob *job,
GL_TEXTURE_2D,
GL_TEXTURE1,
top_offscreen.texture_id);
job->source_is_glyph_atlas = FALSE;
gsk_gl_program_set_uniform1i (job->current_program,
UNIFORM_BLEND_MODE, 0,
gsk_blend_node_get_blend_mode (node));
@@ -3356,6 +3371,7 @@ gsk_gl_render_job_visit_mask_node (GskGLRenderJob *job,
GL_TEXTURE_2D,
GL_TEXTURE1,
mask_offscreen.texture_id);
job->source_is_glyph_atlas = FALSE;
gsk_gl_program_set_uniform1i (job->current_program,
UNIFORM_MASK_MODE, 0,
gsk_mask_node_get_mask_mode (node));
@@ -3392,6 +3408,7 @@ gsk_gl_render_job_visit_color_matrix_node (GskGLRenderJob *job,
GL_TEXTURE_2D,
GL_TEXTURE0,
offscreen.texture_id);
job->source_is_glyph_atlas = FALSE;
gsk_gl_program_set_uniform_matrix (job->current_program,
UNIFORM_COLOR_MATRIX_COLOR_MATRIX, 0,
gsk_color_matrix_node_get_color_matrix (node));
@@ -3474,6 +3491,7 @@ gsk_gl_render_job_visit_gl_shader_node (GskGLRenderJob *job,
GL_TEXTURE_2D,
GL_TEXTURE0 + i,
offscreens[i].texture_id);
job->source_is_glyph_atlas = FALSE;
gsk_gl_program_set_uniform2f (program,
UNIFORM_CUSTOM_SIZE, 0,
node->bounds.size.width,
@@ -3608,6 +3626,7 @@ gsk_gl_render_job_visit_texture (GskGLRenderJob *job,
offscreen.has_mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR,
GL_LINEAR,
offscreen.sync);
job->source_is_glyph_atlas = FALSE;
gsk_gl_render_job_draw_offscreen (job, bounds, &offscreen);
gsk_gl_render_job_end_draw (job);
}
@@ -3645,6 +3664,7 @@ gsk_gl_render_job_visit_texture (GskGLRenderJob *job,
slice->texture_id,
use_mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR,
GL_LINEAR);
job->source_is_glyph_atlas = FALSE;
gsk_gl_render_job_draw_coords (job,
x1, y1, x2, y2,
@@ -3763,6 +3783,7 @@ gsk_gl_render_job_visit_texture_scale_node (GskGLRenderJob *job,
min_filter,
mag_filter,
sync);
job->source_is_glyph_atlas = FALSE;
gsk_gl_render_job_draw_coords (job,
0, 0, clip_rect.size.width, clip_rect.size.height,
u0, v0, u1, v1,
@@ -3804,6 +3825,7 @@ gsk_gl_render_job_visit_texture_scale_node (GskGLRenderJob *job,
slice->texture_id,
min_filter,
mag_filter);
job->source_is_glyph_atlas = FALSE;
gsk_gl_render_job_draw_coords (job,
slice_bounds.origin.x,
slice_bounds.origin.y,
@@ -3836,6 +3858,7 @@ render_texture:
GL_TEXTURE_2D,
GL_TEXTURE0,
texture_id);
job->source_is_glyph_atlas = FALSE;
gsk_gl_render_job_draw_coords (job,
job->offset_x + clip_rect.origin.x,
job->offset_y + clip_rect.origin.y,
@@ -3888,6 +3911,7 @@ gsk_gl_render_job_visit_repeat_node (GskGLRenderJob *job,
GL_TEXTURE_2D,
GL_TEXTURE0,
offscreen.texture_id);
job->source_is_glyph_atlas = FALSE;
gsk_gl_program_set_uniform4f (job->current_program,
UNIFORM_REPEAT_CHILD_BOUNDS, 0,
(node->bounds.origin.x - child_bounds->origin.x) / child_bounds->size.width,
@@ -4382,6 +4406,7 @@ gsk_gl_render_job_render_flipped (GskGLRenderJob *job,
GL_TEXTURE_2D,
GL_TEXTURE0,
texture_id);
job->source_is_glyph_atlas = FALSE;
gsk_gl_render_job_draw_rect (job, &job->viewport);
gsk_gl_render_job_end_draw (job);
}
+3 -3
View File
@@ -75,10 +75,10 @@ void main() {
if (offset < next_offset) {
float f = (offset - curr_offset) / (next_offset - curr_offset);
vec4 curr_color = gsk_premultiply(get_color(i));
vec4 next_color = gsk_premultiply(get_color(i + 1));
vec4 curr_color = get_color(i);
vec4 next_color = get_color(i + 1);
vec4 color = mix(curr_color, next_color, f);
gskSetScaledOutputColor(color, u_alpha);
gskSetScaledOutputColor(gsk_premultiply(color), u_alpha);
return;
}
}
+3 -3
View File
@@ -97,10 +97,10 @@ void main() {
if (offset < next_offset) {
float f = (offset - curr_offset) / (next_offset - curr_offset);
vec4 curr_color = gsk_premultiply(get_color(i));
vec4 next_color = gsk_premultiply(get_color(i + 1));
vec4 curr_color = get_color(i);
vec4 next_color = get_color(i + 1);
vec4 color = mix(curr_color, next_color, f);
gskSetScaledOutputColor(color, u_alpha);
gskSetScaledOutputColor(gsk_premultiply (color), u_alpha);
return;
}
}
+2
View File
@@ -28,6 +28,8 @@ gsk_rounded_rect_shrink (GskRoundedRect r, vec4 amount)
if (r.corner_points1.zw == r.bounds.zy) new_corner_points1.zw = new_bounds.zy;
if (r.corner_points2.xy == r.bounds.zw) new_corner_points2.xy = new_bounds.zw;
if (r.corner_points2.zw == r.bounds.xw) new_corner_points2.zw = new_bounds.xw;
new_corner_points1 = clamp (new_corner_points1, new_bounds.xyxy, new_bounds.zwzw);
new_corner_points2 = clamp (new_corner_points2, new_bounds.xyxy, new_bounds.zwzw);
return GskRoundedRect (new_bounds, new_corner_points1, new_corner_points2);
}
+3 -3
View File
@@ -77,10 +77,10 @@ void main() {
if (offset < next_offset) {
float f = (offset - curr_offset) / (next_offset - curr_offset);
vec4 curr_color = gsk_premultiply(get_color(i));
vec4 next_color = gsk_premultiply(get_color(i + 1));
vec4 curr_color = get_color(i);
vec4 next_color = get_color(i + 1);
vec4 color = mix(curr_color, next_color, f);
gskSetScaledOutputColor(color, u_alpha);
gskSetScaledOutputColor(gsk_premultiply(color), u_alpha);
return;
}
}
+29 -1
View File
@@ -112,4 +112,32 @@ gsk_bounding_box_union (const GskBoundingBox *a,
gsk_bounding_box_init (res, &min, &max);
}
G_END_DECLS
static inline void
gsk_bounding_box_get_corner (const GskBoundingBox *b,
GskCorner c,
graphene_point_t *p)
{
switch (c)
{
case GSK_CORNER_TOP_LEFT:
*p = b->min;
break;
case GSK_CORNER_TOP_RIGHT:
p->x = b->max.x;
p->y = b->min.y;
break;
case GSK_CORNER_BOTTOM_RIGHT:
*p = b->max;
break;
case GSK_CORNER_BOTTOM_LEFT:
p->x = b->min.x;
p->y = b->max.y;
break;
default:
g_assert_not_reached ();
}
}
+1767 -252
View File
File diff suppressed because it is too large Load Diff
+15 -13
View File
@@ -21,7 +21,7 @@
#pragma once
#include "gskpathprivate.h"
#include "gskpathpointprivate.h"
#include "gskpathpoint.h"
#include "gskpathopprivate.h"
#include "gskboundingboxprivate.h"
@@ -34,6 +34,12 @@ GskContour * gsk_standard_contour_new (GskPathFlags
gsize n_ops,
gssize offset);
GskContour * gsk_circle_contour_new (const graphene_point_t *center,
float radius);
GskContour * gsk_rect_contour_new (const graphene_rect_t *rect);
GskContour * gsk_rounded_rect_contour_new (const GskRoundedRect *rounded_rect);
const char * gsk_contour_get_type_name (const GskContour *self);
void gsk_contour_copy (GskContour * dest,
const GskContour *src);
GskContour * gsk_contour_dup (const GskContour *src);
@@ -49,36 +55,32 @@ gboolean gsk_contour_get_stroke_bounds (const GskContou
const GskStroke *stroke,
GskBoundingBox *bounds);
gboolean gsk_contour_foreach (const GskContour *self,
float tolerance,
GskPathForeachFunc func,
gpointer user_data);
void gsk_contour_get_start_end (const GskContour *self,
graphene_point_t *start,
graphene_point_t *end);
int gsk_contour_get_winding (const GskContour *self,
const graphene_point_t *point);
gsize gsk_contour_get_n_ops (const GskContour *self);
gboolean gsk_contour_get_closest_point (const GskContour *self,
const graphene_point_t *point,
float threshold,
GskRealPathPoint *result,
GskPathPoint *result,
float *out_dist);
void gsk_contour_get_position (const GskContour *self,
GskRealPathPoint *point,
const GskPathPoint *point,
graphene_point_t *pos);
void gsk_contour_get_tangent (const GskContour *self,
GskRealPathPoint *point,
const GskPathPoint *point,
GskPathDirection direction,
graphene_vec2_t *tangent);
float gsk_contour_get_curvature (const GskContour *self,
GskRealPathPoint *point,
const GskPathPoint *point,
GskPathDirection direction,
graphene_point_t *center);
void gsk_contour_add_segment (const GskContour *self,
GskPathBuilder *builder,
gboolean emit_move_to,
GskRealPathPoint *start,
GskRealPathPoint *end);
const GskPathPoint *start,
const GskPathPoint *end);
gpointer gsk_contour_init_measure (const GskContour *self,
float tolerance,
@@ -88,9 +90,9 @@ void gsk_contour_free_measure (const GskContou
void gsk_contour_get_point (const GskContour *self,
gpointer measure_data,
float distance,
GskRealPathPoint *result);
GskPathPoint *result);
float gsk_contour_get_distance (const GskContour *self,
GskRealPathPoint *point,
const GskPathPoint *point,
gpointer measure_data);
G_END_DECLS
+61 -2
View File
@@ -2,7 +2,7 @@
* see https://pomax.github.io/bezierinfo/legendre-gauss.html
*/
#if 0
#if defined(USE_64_SAMPLES)
/* n = 64 */
static const double T[] = {
-0.0243502926634244325089558428537156614268871093149758091634531663960566965166295288529853061657116894882370493013671717560479926679408068852617342586968190919443025679363843727751902756254975073084367002129407854253246662805532069172532219089321005870178809284335033318073251039701073379759,
@@ -137,7 +137,8 @@ static const double C[] = {
0.0017832807216964329472960791449719331799593472719279556695308063655858546954239803486698215802150348282744786016134857283616955449868451969230490863774274598030023211055562492709717566919237924255297982774711177411074145151155610163293142044147991553384925940046957893721166251082473659733,
0.0017832807216964329472960791449719331799593472719279556695308063655858546954239803486698215802150348282744786016134857283616955449868451969230490863774274598030023211055562492709717566919237924255297982774711177411074145151155610163293142044147991553384925940046957893721166251082473659733
};
#else
#elif defined(USE_32_SAMPLES)
/* n = 32 */
static double T[] = {
@@ -210,4 +211,62 @@ static double C[] = {
0.0070186100094700966004070637388531825133772207289396032320082356192151241454178686953297376907573215077936155545790593837513204206518026084505878987243348925784479817181234617862457418214505322067610482902501455504204433524520665822704844582452877416001060465891907497519632353148380799619
};
#else
/* n = 24 */
static double T[] = {
-0.0640568928626056260850430826247450385909991954207473934243510817897392835939101078028928761342525090823242273835115756994869112500371756765277735374378372436515481804668409746233647956019276711845937319580510697455314397618513360822351096139837050674073737720614748330506959387258141490546,
0.0640568928626056260850430826247450385909991954207473934243510817897392835939101078028928761342525090823242273835115756994869112500371756765277735374378372436515481804668409746233647956019276711845937319580510697455314397618513360822351096139837050674073737720614748330506959387258141490546,
-0.1911188674736163091586398207570696318404051033147533561489185765880859526918717419824911112452097307135934146013595461392721542943443689459384015952736491888634107638852139839821480663334386199430823059446316182589874503457282270169922471283825305735240671464262733609193984099421023790425,
0.1911188674736163091586398207570696318404051033147533561489185765880859526918717419824911112452097307135934146013595461392721542943443689459384015952736491888634107638852139839821480663334386199430823059446316182589874503457282270169922471283825305735240671464262733609193984099421023790425,
-0.3150426796961633743867932913198102407864782608248172687542301295298821563412434083438735095552082106072251617364030643536658931791308690387340350108862316429911426633492164449851684039691011610681827256891467485494251442677599304969349712405008328365242087382043028815467866505618650936915,
0.3150426796961633743867932913198102407864782608248172687542301295298821563412434083438735095552082106072251617364030643536658931791308690387340350108862316429911426633492164449851684039691011610681827256891467485494251442677599304969349712405008328365242087382043028815467866505618650936915,
-0.4337935076260451384870842319133497124524215109279688080808012846567644070336309140577354304660756168836170633415002629755076381975174699198632370585889341378575229685577710965327823199539830928400741454067377627746745635503614810834602257701251585352190552527778684113280867150779959852524,
0.4337935076260451384870842319133497124524215109279688080808012846567644070336309140577354304660756168836170633415002629755076381975174699198632370585889341378575229685577710965327823199539830928400741454067377627746745635503614810834602257701251585352190552527778684113280867150779959852524,
-0.5454214713888395356583756172183723700107839925876181754336143898305648391795708970958348674408062501977746653313676778948810297400650828985504068941547021866808914316854182653519436295728612315264181208390018064915325250677148594855874434492614547180849377989457776201862945948751249939033,
0.5454214713888395356583756172183723700107839925876181754336143898305648391795708970958348674408062501977746653313676778948810297400650828985504068941547021866808914316854182653519436295728612315264181208390018064915325250677148594855874434492614547180849377989457776201862945948751249939033,
-0.6480936519369755692524957869107476266696582986189567802989336650244483175685397719281177703657272433990519954414744003453347794058626075519074876962003580684127104697893556584036149935275154534232685850207671594298434446955488396349075497667624732345971957611938685137884801129695447597312,
0.6480936519369755692524957869107476266696582986189567802989336650244483175685397719281177703657272433990519954414744003453347794058626075519074876962003580684127104697893556584036149935275154534232685850207671594298434446955488396349075497667624732345971957611938685137884801129695447597312,
-0.7401241915785543642438281030999784255232924870141854568663823682719003386409229324413313561311287943298526270745398288213617461973439599491355223046073660810109486527571776420522757185953076208759863287235084614803697918067466580746275122563457575959399650481778575563118955957829855078072,
0.7401241915785543642438281030999784255232924870141854568663823682719003386409229324413313561311287943298526270745398288213617461973439599491355223046073660810109486527571776420522757185953076208759863287235084614803697918067466580746275122563457575959399650481778575563118955957829855078072,
-0.8200019859739029219539498726697452080761264776678555872439810260013829789535545400822605211725837960666424765858309152369975956748693910897310401393217997751433463343851603146734984964062776585418194561809063555489816762580329418137298754264378316716417347949040725111554705589243953692169,
0.8200019859739029219539498726697452080761264776678555872439810260013829789535545400822605211725837960666424765858309152369975956748693910897310401393217997751433463343851603146734984964062776585418194561809063555489816762580329418137298754264378316716417347949040725111554705589243953692169,
-0.8864155270044010342131543419821967550873330433089200403710379167756748343989591721041235019961817012535295108910075024175885664874383567124270976139069615059721185542370372118538064873468961679956606315961988138722471292807573552657465373246065266349095264290446955886450980216411579068464,
0.8864155270044010342131543419821967550873330433089200403710379167756748343989591721041235019961817012535295108910075024175885664874383567124270976139069615059721185542370372118538064873468961679956606315961988138722471292807573552657465373246065266349095264290446955886450980216411579068464,
-0.9382745520027327585236490017087214496548196580774513466350271759095894960525356709599646415358699555094267057623515929895997449470704383076095012442349544937551633313675972481722466159802428487600880633341786121580661077521685134893546419567859808853944866142065617471979973235700469563606,
0.9382745520027327585236490017087214496548196580774513466350271759095894960525356709599646415358699555094267057623515929895997449470704383076095012442349544937551633313675972481722466159802428487600880633341786121580661077521685134893546419567859808853944866142065617471979973235700469563606,
-0.9747285559713094981983919930081690617411830530401787198115935651071811212809802245386374742817154549827412585755713491144798180281062083910290010368962899139003272102551955405455775700818480561392470581718221938768668731616756379649281934548623489251537698395239432800432811839537332490367,
0.9747285559713094981983919930081690617411830530401787198115935651071811212809802245386374742817154549827412585755713491144798180281062083910290010368962899139003272102551955405455775700818480561392470581718221938768668731616756379649281934548623489251537698395239432800432811839537332490367,
-0.9951872199970213601799974097007368118745976925960028774416005451142838320694577378833972893371157088623453462978965853994497237745715598401409351804188189455255566266162142239452364851560816782389596967291836243391359167365098731808888455424405665558369621091780571617968925046375452278564,
0.9951872199970213601799974097007368118745976925960028774416005451142838320694577378833972893371157088623453462978965853994497237745715598401409351804188189455255566266162142239452364851560816782389596967291836243391359167365098731808888455424405665558369621091780571617968925046375452278564,
};
static double C[] = {
0.1279381953467521569740561652246953718517112395416678824212995763723475915405364024120919775667347423307078678605027534354336365506630173201256407760369958705384835762891562911475479559477218918074170718365754182501974550951925484331523758090745471505157505768499921691572488912345533434646,
0.1279381953467521569740561652246953718517112395416678824212995763723475915405364024120919775667347423307078678605027534354336365506630173201256407760369958705384835762891562911475479559477218918074170718365754182501974550951925484331523758090745471505157505768499921691572488912345533434646,
0.1258374563468282961213753825111836887264033255813454041780915168813938726666625968820381792564211407244125340112283619371640023694354842556219623307075721695505167028832011944572440814161265754364153991752782846305315778293182951298508346824950922490384565834525141570991957343073460241123,
0.1258374563468282961213753825111836887264033255813454041780915168813938726666625968820381792564211407244125340112283619371640023694354842556219623307075721695505167028832011944572440814161265754364153991752782846305315778293182951298508346824950922490384565834525141570991957343073460241123,
0.1216704729278033912044631534762624256070295592038057787774717545126253937177169619177578034307728419129571458407698685455109927385962626203664197972099671299080663146992247474377374928428629909818345130957392521139337403891946990001210368274459006298591636884893163373907763429334385715701,
0.1216704729278033912044631534762624256070295592038057787774717545126253937177169619177578034307728419129571458407698685455109927385962626203664197972099671299080663146992247474377374928428629909818345130957392521139337403891946990001210368274459006298591636884893163373907763429334385715701,
0.1155056680537256013533444839067835598622703113764964705844493600886702535513185499403442576468127956599599096047023274406552399890629831050388267870570157536484442644788074009392626299528272339158271789101012709245867329169327356527615681351864802567093740938014246237226139721687821239517,
0.1155056680537256013533444839067835598622703113764964705844493600886702535513185499403442576468127956599599096047023274406552399890629831050388267870570157536484442644788074009392626299528272339158271789101012709245867329169327356527615681351864802567093740938014246237226139721687821239517,
0.107444270115965634782577342446606222794628690134220021766541640886821866394437105980586727120915236672945076498454815476823439901643102885282830543962266851556251956709331696682107380679861280071851870323872823740641856241992841364843152888380035317713347953732555881218806283399463124951,
0.107444270115965634782577342446606222794628690134220021766541640886821866394437105980586727120915236672945076498454815476823439901643102885282830543962266851556251956709331696682107380679861280071851870323872823740641856241992841364843152888380035317713347953732555881218806283399463124951,
0.097618652104113888269880664464247154427918968853685944083310610022954338577591978348020039690718187482414745713364268645676642419728572107043424944384211806071042042791689191672508012725933985685876262715739521302925263010913644942223616059647289160432915821120275634713911721781926285332,
0.097618652104113888269880664464247154427918968853685944083310610022954338577591978348020039690718187482414745713364268645676642419728572107043424944384211806071042042791689191672508012725933985685876262715739521302925263010913644942223616059647289160432915821120275634713911721781926285332,
0.0861901615319532759171852029837426671850805882379330055884071438612868844607805312688886562972816971732787465671984327992158782827038381983594380916492525003385563462630861694048857276454548529177279961693054540872738963763950131372564031674654030737773100525128451496727198421916322556908,
0.0861901615319532759171852029837426671850805882379330055884071438612868844607805312688886562972816971732787465671984327992158782827038381983594380916492525003385563462630861694048857276454548529177279961693054540872738963763950131372564031674654030737773100525128451496727198421916322556908,
0.0733464814110803057340336152531165181193365098484994714027024906600413884758709348323251422694445551958844309079341158927693012247996928526423877450601776912550600854944985229487704917122675007345403564777169078420148392438502785281584325129303566997853186794893103931008654660416023204965,
0.0733464814110803057340336152531165181193365098484994714027024906600413884758709348323251422694445551958844309079341158927693012247996928526423877450601776912550600854944985229487704917122675007345403564777169078420148392438502785281584325129303566997853186794893103931008654660416023204965,
0.0592985849154367807463677585001085845412001265652134910373765512940983031775082415660683556106090092998654733952492642466909653073834070291103432919838456250955380753837859345492817299145644958959367291816621761687898337760987530926613795554356869343124524696513178977787335055019515914172,
0.0592985849154367807463677585001085845412001265652134910373765512940983031775082415660683556106090092998654733952492642466909653073834070291103432919838456250955380753837859345492817299145644958959367291816621761687898337760987530926613795554356869343124524696513178977787335055019515914172,
0.0442774388174198061686027482113382288593128418338578967413972297210243762822664396343947170155594934934611803046066530352490769669525012630503089839091175520932522330681764807671830570648211944799908348398720715944900305481342571090714940628894962186599515560606956040614089479788668773348,
0.0442774388174198061686027482113382288593128418338578967413972297210243762822664396343947170155594934934611803046066530352490769669525012630503089839091175520932522330681764807671830570648211944799908348398720715944900305481342571090714940628894962186599515560606956040614089479788668773348,
0.0285313886289336631813078159518782864491977979319081166016648047576440056374291434256854254228098755422737224452711633426188506404779428430343631052424983978091405445557790206527391293478807818130301641760878492678184457761229065303399826533483010921962299302202888714000294545957159715602,
0.0285313886289336631813078159518782864491977979319081166016648047576440056374291434256854254228098755422737224452711633426188506404779428430343631052424983978091405445557790206527391293478807818130301641760878492678184457761229065303399826533483010921962299302202888714000294545957159715602,
0.0123412297999871995468056670700372915759100408913665168172873209410917255178811137917987186719204245118391668507179752021919736085531955203240536027970786521356478573832633493407323107496772162595516230980489700767963287958540270795597236457014112169997285946194632806836898378754527134097,
0.0123412297999871995468056670700372915759100408913665168172873209410917255178811137917987186719204245118391668507179752021919736085531955203240536027970786521356478573832633493407323107496772162595516230980489700767963287958540270795597236457014112169997285946194632806836898378754527134097,
};
#endif
+164 -29
View File
@@ -84,6 +84,9 @@ struct _GskCurveClass
const graphene_point_t *point);
float (* get_length_to) (const GskCurve *curve,
float t);
float (* get_at_length) (const GskCurve *curve,
float distance,
float epsilon);
};
/* {{{ Utilities */
@@ -208,6 +211,41 @@ get_length_by_approximation (const GskCurve *curve,
return z * sum;
}
/* Compute the inverse of the arclength using bisection,
* to a given precision
*/
static float
get_t_by_bisection (const GskCurve *curve,
float length,
float epsilon)
{
float t1, t2, t, l;
GskCurve c1;
g_assert (epsilon >= FLT_EPSILON);
t1 = 0;
t2 = 1;
while (t1 < t2)
{
t = (t1 + t2) / 2;
if (t == t1 || t == t2)
break;
gsk_curve_split (curve, t, &c1, NULL);
l = gsk_curve_get_length (&c1);
if (fabsf (length - l) < epsilon)
break;
else if (l < length)
t1 = t;
else
t2 = t;
}
return t;
}
/* }}} */
/* {{{ Line */
@@ -426,6 +464,23 @@ gsk_line_curve_get_length_to (const GskCurve *curve,
return t * graphene_point_distance (&pts[0], &pts[1], NULL, NULL);
}
static float
gsk_line_curve_get_at_length (const GskCurve *curve,
float distance,
float epsilon)
{
const GskLineCurve *self = &curve->line;
const graphene_point_t *pts = self->points;
float length;
length = graphene_point_distance (&pts[0], &pts[1], NULL, NULL);
if (length == 0)
return 0;
return CLAMP (distance / length, 0, 1);
}
static const GskCurveClass GSK_LINE_CURVE_CLASS = {
gsk_line_curve_init,
gsk_line_curve_init_foreach,
@@ -448,6 +503,7 @@ static const GskCurveClass GSK_LINE_CURVE_CLASS = {
gsk_line_curve_get_derivative_at,
gsk_line_curve_get_crossing,
gsk_line_curve_get_length_to,
gsk_line_curve_get_at_length,
};
/* }}} */
@@ -721,6 +777,19 @@ gsk_quad_curve_decompose_curve (const GskCurve *curve,
if (flags & GSK_PATH_FOREACH_ALLOW_QUAD)
return add_curve_func (GSK_PATH_QUAD, self->points, 3, 0.f, user_data);
else if (graphene_point_equal (&curve->conic.points[0], &curve->conic.points[1]) ||
graphene_point_equal (&curve->conic.points[1], &curve->conic.points[2]))
{
if (!graphene_point_equal (&curve->conic.points[0], &curve->conic.points[2]))
return add_curve_func (GSK_PATH_LINE,
(graphene_point_t[2]) {
curve->conic.points[0],
curve->conic.points[2],
},
2, 0.f, user_data);
else
return TRUE;
}
else if (flags & GSK_PATH_FOREACH_ALLOW_CUBIC)
{
GskCurve c;
@@ -828,6 +897,14 @@ gsk_quad_curve_get_length_to (const GskCurve *curve,
return get_length_by_approximation (curve, t);
}
static float
gsk_quad_curve_get_at_length (const GskCurve *curve,
float t,
float epsilon)
{
return get_t_by_bisection (curve, t, epsilon);
}
static const GskCurveClass GSK_QUAD_CURVE_CLASS = {
gsk_quad_curve_init,
gsk_quad_curve_init_foreach,
@@ -850,9 +927,10 @@ static const GskCurveClass GSK_QUAD_CURVE_CLASS = {
gsk_quad_curve_get_derivative_at,
gsk_quad_curve_get_crossing,
gsk_quad_curve_get_length_to,
gsk_quad_curve_get_at_length,
};
/* }}} */
/* }}} */
/* {{{ Cubic */
static void
@@ -1298,6 +1376,14 @@ gsk_cubic_curve_get_length_to (const GskCurve *curve,
return get_length_by_approximation (curve, t);
}
static float
gsk_cubic_curve_get_at_length (const GskCurve *curve,
float t,
float epsilon)
{
return get_t_by_bisection (curve, t, epsilon);
}
static const GskCurveClass GSK_CUBIC_CURVE_CLASS = {
gsk_cubic_curve_init,
gsk_cubic_curve_init_foreach,
@@ -1320,6 +1406,7 @@ static const GskCurveClass GSK_CUBIC_CURVE_CLASS = {
gsk_cubic_curve_get_derivative_at,
gsk_cubic_curve_get_crossing,
gsk_cubic_curve_get_length_to,
gsk_cubic_curve_get_at_length,
};
/* }}} */
@@ -1853,7 +1940,20 @@ gsk_conic_curve_decompose_or_add (const GskCurve *curve,
GskCurveAddCurveFunc add_curve_func,
gpointer user_data)
{
if (gsk_conic_is_close_to_cubic (curve, cubic, tolerance))
if (graphene_point_equal (&curve->conic.points[0], &curve->conic.points[1]) ||
graphene_point_equal (&curve->conic.points[1], &curve->conic.points[3]))
{
if (!graphene_point_equal (&curve->conic.points[0], &curve->conic.points[3]))
return add_curve_func (GSK_PATH_LINE,
(graphene_point_t[2]) {
curve->conic.points[0],
curve->conic.points[3],
},
2, 0.f, user_data);
else
return TRUE;
}
else if (gsk_conic_is_close_to_cubic (curve, cubic, tolerance))
return add_curve_func (GSK_PATH_CUBIC, cubic->cubic.points, 4, 0.f, user_data);
else
{
@@ -1895,7 +1995,7 @@ gsk_conic_curve_decompose_curve (const GskCurve *curve,
return gsk_conic_curve_decompose_or_add (curve, &c, tolerance, add_curve_func, user_data);
}
/* FIXME: Quadratic (or conic?) approximation */
/* FIXME: Quadratic approximation */
return gsk_conic_curve_decompose (curve,
tolerance,
gsk_curve_add_line_cb,
@@ -1992,6 +2092,14 @@ gsk_conic_curve_get_length_to (const GskCurve *curve,
return get_length_by_approximation (curve, t);
}
static float
gsk_conic_curve_get_at_length (const GskCurve *curve,
float t,
float epsilon)
{
return get_t_by_bisection (curve, t, epsilon);
}
static const GskCurveClass GSK_CONIC_CURVE_CLASS = {
gsk_conic_curve_init,
gsk_conic_curve_init_foreach,
@@ -2014,6 +2122,7 @@ static const GskCurveClass GSK_CONIC_CURVE_CLASS = {
gsk_conic_curve_get_derivative_at,
gsk_conic_curve_get_crossing,
gsk_conic_curve_get_length_to,
gsk_conic_curve_get_at_length,
};
/* }}} */
@@ -2363,32 +2472,7 @@ gsk_curve_at_length (const GskCurve *curve,
float length,
float epsilon)
{
float t1, t2, t, l;
GskCurve c1;
g_assert (epsilon >= FLT_EPSILON);
t1 = 0;
t2 = 1;
while (t1 < t2)
{
t = (t1 + t2) / 2;
if (t == t1 || t == t2)
break;
gsk_curve_split (curve, t, &c1, NULL);
l = gsk_curve_get_length (&c1);
if (fabsf (length - l) < epsilon)
break;
else if (l < length)
t1 = t;
else
t2 = t;
}
return t;
return get_class (curve->op)->get_at_length (curve, length, epsilon);
}
static inline void
@@ -2497,6 +2581,57 @@ gsk_curve_get_curvature_points (const GskCurve *curve,
return filter_allowable (t, n);
}
/* Find cusps inside the open interval from 0 to 1.
*
* According to Stone & deRose, A Geometric Characterization
* of Parametric Cubic curves, a necessary and sufficient
* condition is that the first derivative vanishes.
*/
int
gsk_curve_get_cusps (const GskCurve *curve,
float t[2])
{
const graphene_point_t *pts = curve->cubic.points;
graphene_point_t p[3];
float ax, bx, cx;
float ay, by, cy;
float tx[3];
int nx;
int n = 0;
if (curve->op != GSK_PATH_CUBIC)
return 0;
p[0].x = 3 * (pts[1].x - pts[0].x);
p[0].y = 3 * (pts[1].y - pts[0].y);
p[1].x = 3 * (pts[2].x - pts[1].x);
p[1].y = 3 * (pts[2].y - pts[1].y);
p[2].x = 3 * (pts[3].x - pts[2].x);
p[2].y = 3 * (pts[3].y - pts[2].y);
ax = p[0].x - 2 * p[1].x + p[2].x;
bx = - 2 * p[0].x + 2 * p[1].x;
cx = p[0].x;
nx = solve_quadratic (ax, bx, cx, tx);
nx = filter_allowable (tx, nx);
ay = p[0].y - 2 * p[1].y + p[2].y;
by = - 2 * p[0].y + 2 * p[1].y;
cy = p[0].y;
for (int i = 0; i < nx; i++)
{
float ti = tx[i];
if (0 < ti && ti < 1 &&
fabsf (ay * ti * ti + by * ti + cy) < 0.001)
t[n++] = ti;
}
return n;
}
/* }}} */
/* vim:set foldmethod=marker expandtab: */
+4 -1
View File
@@ -181,9 +181,12 @@ float gsk_curve_at_length (const GskCurve
float distance,
float epsilon);
int gsk_curve_get_curvature_points (const GskCurve * curve,
int gsk_curve_get_curvature_points (const GskCurve *curve,
float t[3]);
int gsk_curve_get_cusps (const GskCurve *curve,
float t[2]);
G_END_DECLS
+56 -612
View File
@@ -23,8 +23,8 @@
#include "gskcurveprivate.h"
#include "gskpathbuilder.h"
#include "gskpathpointprivate.h"
#include "gsksplineprivate.h"
#include "gskpathpoint.h"
#include "gskcontourprivate.h"
/**
* GskPath:
@@ -66,6 +66,8 @@ struct _GskPath
G_DEFINE_BOXED_TYPE (GskPath, gsk_path, gsk_path_ref, gsk_path_unref)
/* {{{ Private API */
GskPath *
gsk_path_new_from_contours (const GSList *contours)
{
@@ -110,6 +112,31 @@ gsk_path_new_from_contours (const GSList *contours)
return path;
}
const GskContour *
gsk_path_get_contour (const GskPath *self,
gsize i)
{
if (i < self->n_contours)
return self->contours[i];
else
return NULL;
}
GskPathFlags
gsk_path_get_flags (const GskPath *self)
{
return self->flags;
}
gsize
gsk_path_get_n_contours (const GskPath *self)
{
return self->n_contours;
}
/* }}} */
/* {{{ Public API */
/**
* gsk_path_ref:
* @self: a `GskPath`
@@ -153,22 +180,6 @@ gsk_path_unref (GskPath *self)
g_free (self);
}
const GskContour *
gsk_path_get_contour (const GskPath *self,
gsize i)
{
if (i < self->n_contours)
return self->contours[i];
else
return NULL;
}
GskPathFlags
gsk_path_get_flags (const GskPath *self)
{
return self->flags;
}
/**
* gsk_path_print:
* @self: a `GskPath`
@@ -295,20 +306,6 @@ gsk_path_to_cairo (GskPath *self,
cr);
}
/*< private >
* gsk_path_get_n_contours:
* @path: a `GskPath`
*
* Gets the number of contours @path is composed out of.
*
* Returns: the number of contours in @path
*/
gsize
gsk_path_get_n_contours (const GskPath *self)
{
return self->n_contours;
}
/**
* gsk_path_is_empty:
* @self: a `GskPath`
@@ -511,17 +508,19 @@ gboolean
gsk_path_get_start_point (GskPath *self,
GskPathPoint *result)
{
GskRealPathPoint *res = (GskRealPathPoint *) result;
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (result != NULL, FALSE);
if (self->n_contours == 0)
return FALSE;
res->contour = 0;
res->idx = 1;
res->t = 0;
/* Conceptually, there is always a move at the
* beginning, which jumps from where to the start
* point of the contour, so we use idx == 1 here.
*/
result->contour = 0;
result->idx = 1;
result->t = 0;
return TRUE;
}
@@ -544,17 +543,15 @@ gboolean
gsk_path_get_end_point (GskPath *self,
GskPathPoint *result)
{
GskRealPathPoint *res = (GskRealPathPoint *) result;
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (result != NULL, FALSE);
if (self->n_contours == 0)
return FALSE;
res->contour = self->n_contours - 1;
res->idx = gsk_contour_get_n_ops (self->contours[self->n_contours - 1]) - 1;
res->t = 1;
result->contour = self->n_contours - 1;
result->idx = gsk_contour_get_n_ops (self->contours[self->n_contours - 1]) - 1;
result->t = 1;
return TRUE;
}
@@ -565,6 +562,7 @@ gsk_path_get_end_point (GskPath *self,
* @point: the point
* @threshold: maximum allowed distance
* @result: (out caller-allocates): return location for the closest point
* @distance: (out) (optional): return location for the distance
*
* Computes the closest point on the path to the given point
* and sets the @result to it.
@@ -581,9 +579,9 @@ gboolean
gsk_path_get_closest_point (GskPath *self,
const graphene_point_t *point,
float threshold,
GskPathPoint *result)
GskPathPoint *result,
float *distance)
{
GskRealPathPoint *res = (GskRealPathPoint *) result;
gboolean found;
g_return_val_if_fail (self != NULL, FALSE);
@@ -595,19 +593,26 @@ gsk_path_get_closest_point (GskPath *self,
for (int i = 0; i < self->n_contours; i++)
{
float distance;
float dist;
if (gsk_contour_get_closest_point (self->contours[i], point, threshold, res, &distance))
if (gsk_contour_get_closest_point (self->contours[i], point, threshold, result, &dist))
{
found = TRUE;
res->contour = i;
threshold = distance;
g_assert (0 <= result->t && result->t <= 1);
result->contour = i;
threshold = dist;
if (distance)
*distance = dist;
}
}
return found;
}
/* }}} */
/* {{{ Foreach and decomposition */
/**
* gsk_path_foreach:
* @self: a `GskPath`
@@ -805,574 +810,13 @@ gsk_path_foreach_with_tolerance (GskPath *self,
for (i = 0; i < self->n_contours; i++)
{
if (!gsk_contour_foreach (self->contours[i], tolerance, func, user_data))
if (!gsk_contour_foreach (self->contours[i], func, user_data))
return FALSE;
}
return TRUE;
}
/* path parser and utilities */
/* }}} */
static void
skip_whitespace (const char **p)
{
while (g_ascii_isspace (**p))
(*p)++;
}
static void
skip_optional_comma (const char **p)
{
skip_whitespace (p);
if (**p == ',')
(*p)++;
}
static gboolean
parse_number (const char **p,
double *c)
{
char *e;
*c = g_ascii_strtod (*p, &e);
if (e == *p)
return FALSE;
*p = e;
skip_optional_comma (p);
return TRUE;
}
static gboolean
parse_coordinate (const char **p,
double *c)
{
return parse_number (p, c);
}
static gboolean
parse_coordinate_pair (const char **p,
double *x,
double *y)
{
double xx, yy;
const char *o = *p;
if (!parse_coordinate (p, &xx))
{
*p = o;
return FALSE;
}
if (!parse_coordinate (p, &yy))
{
*p = o;
return FALSE;
}
*x = xx;
*y = yy;
return TRUE;
}
static gboolean
parse_nonnegative_number (const char **p,
double *x)
{
const char *o = *p;
double n;
if (!parse_number (p, &n))
return FALSE;
if (n < 0)
{
*p = o;
return FALSE;
}
*x = n;
return TRUE;
}
/* This fixes a flaw in our use of strchr() below:
*
* If p already points at the end of the string,
* we misinterpret strchr ("xyz", *p) returning
* non-NULL to mean that we can increment p.
*
* But strchr() will return a pointer to the
* final NUL byte in this case, and we walk off
* the end of the string. Oops
*/
static inline char *
_strchr (const char *str,
int c)
{
if (c == 0)
return NULL;
else
return strchr (str, c);
}
static gboolean
parse_flag (const char **p,
gboolean *f)
{
skip_whitespace (p);
if (_strchr ("01", **p))
{
*f = **p == '1';
(*p)++;
skip_optional_comma (p);
return TRUE;
}
return FALSE;
}
static gboolean
parse_command (const char **p,
char *cmd)
{
char *s;
const char *allowed;
if (*cmd == 'X')
allowed = "mM";
else
allowed = "mMhHvVzZlLcCsStTqQaAoO";
skip_whitespace (p);
s = _strchr (allowed, **p);
if (s)
{
*cmd = *s;
(*p)++;
return TRUE;
}
return FALSE;
}
/**
* gsk_path_parse:
* @string: a string
*
* This is a convenience function that constructs a `GskPath`
* from a serialized form.
*
* The string is expected to be in (a superset of)
* [SVG path syntax](https://www.w3.org/TR/SVG11/paths.html#PathData),
* as e.g. produced by [method@Gsk.Path.to_string].
*
* A high-level summary of the syntax:
*
* - `M x y` Move to `(x, y)`
* - `L x y` Add a line from the current point to `(x, y)`
* - `Q x1 y1 x2 y2` Add a quadratic Bézier from the current point to `(x2, y2)`, with control point `(x1, y1)`
* - `C x1 y1 x2 y2 x3 y3` Add a cubic Bézier from the current point to `(x3, y3)`, with control points `(x1, y1)` and `(x2, y2)`
* - `Z` Close the contour by drawing a line back to the start point
* - `H x` Add a horizontal line from the current point to the given x value
* - `V y` Add a vertical line from the current point to the given y value
* - `T x2 y2` Add a quadratic Bézier, using the reflection of the previous segments' control point as control point
* - `S x2 y2 x3 y3` Add a cubic Bézier, using the reflection of the previous segments' second control point as first control point
* - `A rx ry r l s x y` Add an elliptical arc from the current point to `(x, y)` with radii rx and ry. See the SVG documentation for how the other parameters influence the arc.
* - `O x1 y1 x2 y2 w` Add a rational quadratic Bézier from the current point to `(x2, y2)` with control point `(x1, y1)` and weight `w`.
*
* All the commands have lowercase variants that interpret coordinates
* relative to the current point.
*
* The `O` command is an extension that is not supported in SVG.
*
* Returns: (nullable): a new `GskPath`, or `NULL` if @string could not be parsed
*
* Since: 4.14
*/
GskPath *
gsk_path_parse (const char *string)
{
GskPathBuilder *builder;
double x, y;
double prev_x1, prev_y1;
double path_x, path_y;
const char *p;
char cmd;
char prev_cmd;
gboolean after_comma;
gboolean repeat;
builder = gsk_path_builder_new ();
cmd = 'X';
path_x = path_y = 0;
x = y = 0;
prev_x1 = prev_y1 = 0;
after_comma = FALSE;
p = string;
while (*p)
{
prev_cmd = cmd;
repeat = !parse_command (&p, &cmd);
if (after_comma && !repeat)
goto error;
switch (cmd)
{
case 'X':
goto error;
case 'Z':
case 'z':
if (repeat)
goto error;
else
{
gsk_path_builder_close (builder);
x = path_x;
y = path_y;
}
break;
case 'M':
case 'm':
{
double x1, y1;
if (parse_coordinate_pair (&p, &x1, &y1))
{
if (cmd == 'm')
{
x1 += x;
y1 += y;
}
if (repeat)
gsk_path_builder_line_to (builder, x1, y1);
else
{
gsk_path_builder_move_to (builder, x1, y1);
if (_strchr ("zZX", prev_cmd))
{
path_x = x1;
path_y = y1;
}
}
x = x1;
y = y1;
}
else
goto error;
}
break;
case 'L':
case 'l':
{
double x1, y1;
if (parse_coordinate_pair (&p, &x1, &y1))
{
if (cmd == 'l')
{
x1 += x;
y1 += y;
}
if (_strchr ("zZ", prev_cmd))
{
gsk_path_builder_move_to (builder, x, y);
path_x = x;
path_y = y;
}
gsk_path_builder_line_to (builder, x1, y1);
x = x1;
y = y1;
}
else
goto error;
}
break;
case 'H':
case 'h':
{
double x1;
if (parse_coordinate (&p, &x1))
{
if (cmd == 'h')
x1 += x;
if (_strchr ("zZ", prev_cmd))
{
gsk_path_builder_move_to (builder, x, y);
path_x = x;
path_y = y;
}
gsk_path_builder_line_to (builder, x1, y);
x = x1;
}
else
goto error;
}
break;
case 'V':
case 'v':
{
double y1;
if (parse_coordinate (&p, &y1))
{
if (cmd == 'v')
y1 += y;
if (_strchr ("zZ", prev_cmd))
{
gsk_path_builder_move_to (builder, x, y);
path_x = x;
path_y = y;
}
gsk_path_builder_line_to (builder, x, y1);
y = y1;
}
else
goto error;
}
break;
case 'C':
case 'c':
{
double x0, y0, x1, y1, x2, y2;
if (parse_coordinate_pair (&p, &x0, &y0) &&
parse_coordinate_pair (&p, &x1, &y1) &&
parse_coordinate_pair (&p, &x2, &y2))
{
if (cmd == 'c')
{
x0 += x;
y0 += y;
x1 += x;
y1 += y;
x2 += x;
y2 += y;
}
if (_strchr ("zZ", prev_cmd))
{
gsk_path_builder_move_to (builder, x, y);
path_x = x;
path_y = y;
}
gsk_path_builder_cubic_to (builder, x0, y0, x1, y1, x2, y2);
prev_x1 = x1;
prev_y1 = y1;
x = x2;
y = y2;
}
else
goto error;
}
break;
case 'S':
case 's':
{
double x0, y0, x1, y1, x2, y2;
if (parse_coordinate_pair (&p, &x1, &y1) &&
parse_coordinate_pair (&p, &x2, &y2))
{
if (cmd == 's')
{
x1 += x;
y1 += y;
x2 += x;
y2 += y;
}
if (_strchr ("CcSs", prev_cmd))
{
x0 = 2 * x - prev_x1;
y0 = 2 * y - prev_y1;
}
else
{
x0 = x;
y0 = y;
}
if (_strchr ("zZ", prev_cmd))
{
gsk_path_builder_move_to (builder, x, y);
path_x = x;
path_y = y;
}
gsk_path_builder_cubic_to (builder, x0, y0, x1, y1, x2, y2);
prev_x1 = x1;
prev_y1 = y1;
x = x2;
y = y2;
}
else
goto error;
}
break;
case 'Q':
case 'q':
{
double x1, y1, x2, y2;
if (parse_coordinate_pair (&p, &x1, &y1) &&
parse_coordinate_pair (&p, &x2, &y2))
{
if (cmd == 'q')
{
x1 += x;
y1 += y;
x2 += x;
y2 += y;
}
if (_strchr ("zZ", prev_cmd))
{
gsk_path_builder_move_to (builder, x, y);
path_x = x;
path_y = y;
}
gsk_path_builder_quad_to (builder, x1, y1, x2, y2);
prev_x1 = x1;
prev_y1 = y1;
x = x2;
y = y2;
}
else
goto error;
}
break;
case 'T':
case 't':
{
double x1, y1, x2, y2;
if (parse_coordinate_pair (&p, &x2, &y2))
{
if (cmd == 't')
{
x2 += x;
y2 += y;
}
if (_strchr ("QqTt", prev_cmd))
{
x1 = 2 * x - prev_x1;
y1 = 2 * y - prev_y1;
}
else
{
x1 = x;
y1 = y;
}
if (_strchr ("zZ", prev_cmd))
{
gsk_path_builder_move_to (builder, x, y);
path_x = x;
path_y = y;
}
gsk_path_builder_quad_to (builder, x1, y1, x2, y2);
prev_x1 = x1;
prev_y1 = y1;
x = x2;
y = y2;
}
else
goto error;
}
break;
case 'O':
case 'o':
{
double x1, y1, x2, y2, weight;
if (parse_coordinate_pair (&p, &x1, &y1) &&
parse_coordinate_pair (&p, &x2, &y2) &&
parse_nonnegative_number (&p, &weight))
{
if (cmd == 'c')
{
x1 += x;
y1 += y;
x2 += x;
y2 += y;
}
if (_strchr ("zZ", prev_cmd))
{
gsk_path_builder_move_to (builder, x, y);
path_x = x;
path_y = y;
}
gsk_path_builder_conic_to (builder, x1, y1, x2, y2, weight);
x = x2;
y = y2;
}
else
goto error;
}
break;
case 'A':
case 'a':
{
double rx, ry;
double x_axis_rotation;
int large_arc, sweep;
double x1, y1;
if (parse_nonnegative_number (&p, &rx) &&
parse_nonnegative_number (&p, &ry) &&
parse_number (&p, &x_axis_rotation) &&
parse_flag (&p, &large_arc) &&
parse_flag (&p, &sweep) &&
parse_coordinate_pair (&p, &x1, &y1))
{
if (cmd == 'a')
{
x1 += x;
y1 += y;
}
if (_strchr ("zZ", prev_cmd))
{
gsk_path_builder_move_to (builder, x, y);
path_x = x;
path_y = y;
}
gsk_path_builder_svg_arc_to (builder,
rx, ry, x_axis_rotation,
large_arc, sweep,
x1, y1);
x = x1;
y = y1;
}
else
goto error;
}
break;
default:
goto error;
}
after_comma = (p > string) && p[-1] == ',';
}
if (after_comma)
goto error;
return gsk_path_builder_free_to_path (builder);
error:
//g_warning ("Can't parse string '%s' as GskPath, error at %ld", string, p - string);
gsk_path_builder_unref (builder);
return NULL;
}
/* vim:set foldmethod=marker expandtab: */
+2 -1
View File
@@ -135,7 +135,8 @@ GDK_AVAILABLE_IN_4_14
gboolean gsk_path_get_closest_point (GskPath *self,
const graphene_point_t *point,
float threshold,
GskPathPoint *result);
GskPathPoint *result,
float *distance);
GDK_AVAILABLE_IN_4_14
gboolean gsk_path_foreach (GskPath *self,
+321 -117
View File
@@ -24,6 +24,8 @@
#include "gskpathbuilder.h"
#include "gskpathprivate.h"
#include "gskcurveprivate.h"
#include "gskpathpointprivate.h"
#include "gskcontourprivate.h"
/**
@@ -66,6 +68,9 @@
*
* This is similar to how paths are drawn in Cairo.
*
* Note that `GskPathBuilder` will reduce the degree of added Bézier
* curves as much as possible, to simplify rendering.
*
* Since: 4.14
*/
@@ -445,9 +450,6 @@ gsk_path_builder_add_cairo_path (GskPathBuilder *self,
*
* The path is going around the rectangle in clockwise direction.
*
* If the width or height of the rectangle is negative, the start
* point will be on the right or bottom, respectively.
*
* If the the width or height are 0, the path will be a closed
* horizontal or vertical line. If both are 0, it'll be a closed dot.
*
@@ -457,20 +459,13 @@ void
gsk_path_builder_add_rect (GskPathBuilder *self,
const graphene_rect_t *rect)
{
graphene_point_t current;
graphene_rect_t r;
g_return_if_fail (self != NULL);
g_return_if_fail (rect != NULL);
current = self->current_point;
gsk_path_builder_move_to (self, rect->origin.x, rect->origin.y);
gsk_path_builder_rel_line_to (self, rect->size.width, 0);
gsk_path_builder_rel_line_to (self, 0, rect->size.height);
gsk_path_builder_rel_line_to (self, - rect->size.width, 0);
gsk_path_builder_close (self);
self->current_point = current;
graphene_rect_normalize_r (rect, &r);
gsk_path_builder_add_contour (self, gsk_rect_contour_new (&r));
}
/**
@@ -488,59 +483,10 @@ void
gsk_path_builder_add_rounded_rect (GskPathBuilder *self,
const GskRoundedRect *rect)
{
graphene_point_t current;
g_return_if_fail (self != NULL);
g_return_if_fail (rect != NULL);
current = self->current_point;
gsk_path_builder_move_to (self,
rect->bounds.origin.x + rect->corner[GSK_CORNER_TOP_LEFT].width,
rect->bounds.origin.y);
/* top */
gsk_path_builder_line_to (self,
rect->bounds.origin.x + rect->bounds.size.width - rect->corner[GSK_CORNER_TOP_RIGHT].width,
rect->bounds.origin.y);
/* topright corner */
gsk_path_builder_arc_to (self,
rect->bounds.origin.x + rect->bounds.size.width,
rect->bounds.origin.y,
rect->bounds.origin.x + rect->bounds.size.width,
rect->bounds.origin.y + rect->corner[GSK_CORNER_TOP_RIGHT].height);
/* right */
gsk_path_builder_line_to (self,
rect->bounds.origin.x + rect->bounds.size.width,
rect->bounds.origin.y + rect->bounds.size.height - rect->corner[GSK_CORNER_BOTTOM_RIGHT].height);
/* bottomright corner */
gsk_path_builder_arc_to (self,
rect->bounds.origin.x + rect->bounds.size.width,
rect->bounds.origin.y + rect->bounds.size.height,
rect->bounds.origin.x + rect->bounds.size.width - rect->corner[GSK_CORNER_BOTTOM_RIGHT].width,
rect->bounds.origin.y + rect->bounds.size.height);
/* bottom */
gsk_path_builder_line_to (self,
rect->bounds.origin.x + rect->corner[GSK_CORNER_BOTTOM_LEFT].width,
rect->bounds.origin.y + rect->bounds.size.height);
/* bottomleft corner */
gsk_path_builder_arc_to (self,
rect->bounds.origin.x,
rect->bounds.origin.y + rect->bounds.size.height,
rect->bounds.origin.x,
rect->bounds.origin.y + rect->bounds.size.height - rect->corner[GSK_CORNER_BOTTOM_LEFT].height);
/* left */
gsk_path_builder_line_to (self,
rect->bounds.origin.x,
rect->bounds.origin.y + rect->corner[GSK_CORNER_TOP_LEFT].height);
/* topleft corner */
gsk_path_builder_arc_to (self,
rect->bounds.origin.x,
rect->bounds.origin.y,
rect->bounds.origin.x + rect->corner[GSK_CORNER_TOP_LEFT].width,
rect->bounds.origin.y);
/* done */
gsk_path_builder_close (self);
self->current_point = current;
gsk_path_builder_add_contour (self, gsk_rounded_rect_contour_new (rect));
}
/**
@@ -553,6 +499,8 @@ gsk_path_builder_add_rounded_rect (GskPathBuilder *self,
*
* The path is going around the circle in clockwise direction.
*
* If @radius is zero, the contour will be a closed point.
*
* Since: 4.14
*/
void
@@ -560,34 +508,11 @@ gsk_path_builder_add_circle (GskPathBuilder *self,
const graphene_point_t *center,
float radius)
{
graphene_point_t current;
g_return_if_fail (self != NULL);
g_return_if_fail (center != NULL);
g_return_if_fail (radius > 0);
g_return_if_fail (radius >= 0);
current = self->current_point;
gsk_path_builder_move_to (self, center->x + radius, center->y);
// bottom right quarter
gsk_path_builder_arc_to (self,
center->x + radius, center->y + radius,
center->x, center->y + radius);
// bottom left quarter
gsk_path_builder_arc_to (self,
center->x - radius, center->y + radius,
center->x - radius, center->y);
// top left quarter
gsk_path_builder_arc_to (self,
center->x - radius, center->y - radius,
center->x, center->y - radius);
// top right quarter
gsk_path_builder_arc_to (self,
center->x + radius, center->y - radius,
center->x + radius, center->y);
// done
gsk_path_builder_close (self);
self->current_point = current;
gsk_path_builder_add_contour (self, gsk_circle_contour_new (center, radius));
}
/**
@@ -703,6 +628,40 @@ gsk_path_builder_rel_line_to (GskPathBuilder *self,
self->current_point.y + y);
}
static inline void
closest_point (const graphene_point_t *p,
const graphene_point_t *a,
const graphene_point_t *b,
graphene_point_t *q)
{
graphene_vec2_t n;
graphene_vec2_t ap;
float t;
graphene_vec2_init (&n, b->x - a->x, b->y - a->y);
graphene_vec2_init (&ap, p->x - a->x, p->y - a->y);
t = graphene_vec2_dot (&ap, &n) / graphene_vec2_dot (&n, &n);
q->x = a->x + t * (b->x - a->x);
q->y = a->y + t * (b->y - a->y);
}
static inline gboolean
collinear (const graphene_point_t *p,
const graphene_point_t *a,
const graphene_point_t *b)
{
graphene_point_t q;
if (graphene_point_equal (a, b))
return TRUE;
closest_point (p, a, b, &q);
return graphene_point_near (p, &q, 0.001);
}
/**
* gsk_path_builder_quad_to:
* @self: a #GskPathBuilder
@@ -730,15 +689,52 @@ gsk_path_builder_quad_to (GskPathBuilder *self,
float x2,
float y2)
{
graphene_point_t p0 = self->current_point;
graphene_point_t p1 = GRAPHENE_POINT_INIT (x1, y1);
graphene_point_t p2 = GRAPHENE_POINT_INIT (x2, y2);
g_return_if_fail (self != NULL);
if (collinear (&p0, &p1, &p2))
{
GskBoundingBox bb;
/* We simplify degenerate quads to one or two lines */
if (!gsk_bounding_box_contains_point (gsk_bounding_box_init (&bb, &p0, &p2), &p1))
{
GskCurve c;
gsk_curve_init_foreach (&c, GSK_PATH_QUAD,
(const graphene_point_t []) { p0, p1, p2 },
3, 0.f);
gsk_curve_get_tight_bounds (&c, &bb);
for (int i = 0; i < 4; i++)
{
graphene_point_t q;
gsk_bounding_box_get_corner (&bb, i, &q);
if (graphene_point_equal (&p0, &q) ||
graphene_point_equal (&p2, &q))
{
gsk_bounding_box_get_corner (&bb, (i + 2) % 4, &q);
gsk_path_builder_line_to (self, q.x, q.y);
gsk_path_builder_append_current (self,
GSK_PATH_QUAD,
2, (graphene_point_t[2]) { q, q });
break;
}
}
}
gsk_path_builder_line_to (self, x2, y2);
return;
}
self->flags &= ~GSK_PATH_FLAT;
gsk_path_builder_append_current (self,
GSK_PATH_QUAD,
2, (graphene_point_t[2]) {
GRAPHENE_POINT_INIT (x1, y1),
GRAPHENE_POINT_INIT (x2, y2)
});
2, (graphene_point_t[2]) { p1, p2 });
}
/**
@@ -774,6 +770,38 @@ gsk_path_builder_rel_quad_to (GskPathBuilder *self,
self->current_point.y + y2);
}
static gboolean
point_is_between (const graphene_point_t *q,
const graphene_point_t *p0,
const graphene_point_t *p1)
{
return collinear (p0, p1, q) &&
fabsf (graphene_point_distance (p0, q, NULL, NULL) + graphene_point_distance (p1, q, NULL, NULL) - graphene_point_distance (p0, p1, NULL, NULL)) < 0.001;
}
static gboolean
bounding_box_corner_between (const GskBoundingBox *bb,
const graphene_point_t *p0,
const graphene_point_t *p1,
graphene_point_t *p)
{
for (int i = 0; i < 4; i++)
{
graphene_point_t q;
gsk_bounding_box_get_corner (bb, i, &q);
if (point_is_between (&q, p0, p1))
{
*p = q;
return TRUE;
}
}
return FALSE;
}
/**
* gsk_path_builder_cubic_to:
* @self: a `GskPathBuilder`
@@ -806,16 +834,151 @@ gsk_path_builder_cubic_to (GskPathBuilder *self,
float x3,
float y3)
{
graphene_point_t p0 = self->current_point;
graphene_point_t p1 = GRAPHENE_POINT_INIT (x1, y1);
graphene_point_t p2 = GRAPHENE_POINT_INIT (x2, y2);
graphene_point_t p3 = GRAPHENE_POINT_INIT (x3, y3);
graphene_point_t p, q;
gboolean p01, p12, p23;
g_return_if_fail (self != NULL);
p01 = graphene_point_equal (&p0, &p1);
p12 = graphene_point_equal (&p1, &p2);
p23 = graphene_point_equal (&p2, &p3);
if (p01 && p12 && p23)
return;
if ((p01 && p23) || (p12 && (p01 || p23)))
{
gsk_path_builder_line_to (self, x3, y3);
return;
}
if (collinear (&p0, &p1, &p2) &&
collinear (&p1, &p2, &p3) &&
(!p12 || collinear (&p0, &p1, &p3)))
{
GskBoundingBox bb;
gboolean p1in, p2in;
gsk_bounding_box_init (&bb, &p0, &p3);
p1in = gsk_bounding_box_contains_point (&bb, &p1);
p2in = gsk_bounding_box_contains_point (&bb, &p2);
if (p1in && p2in)
{
gsk_path_builder_line_to (self, x3, y3);
}
else
{
GskCurve c;
gsk_curve_init_foreach (&c,
GSK_PATH_CUBIC,
(const graphene_point_t[]) { p0, p1, p2, p3 },
4,
0.f);
gsk_curve_get_tight_bounds (&c, &bb);
if (!p1in)
{
/* Find the intersection of bb with p0 - p1.
* It must be a corner
*/
bounding_box_corner_between (&bb, &p0, &p1, &p);
gsk_path_builder_line_to (self, p.x, p.y);
gsk_path_builder_append_current (self,
GSK_PATH_QUAD,
2, (graphene_point_t[2]) { p, p });
}
if (!p2in)
{
/* Find the intersection of bb with p2 - p3. */
bounding_box_corner_between (&bb, &p3, &p2, &p);
gsk_path_builder_line_to (self, p.x, p.y);
gsk_path_builder_append_current (self,
GSK_PATH_QUAD,
2, (graphene_point_t[2]) { p, p });
}
gsk_path_builder_line_to (self, x3, y3);
}
return;
}
/* reduce to a quadratic if possible */
graphene_point_interpolate (&p0, &p1, 1.5, &p);
graphene_point_interpolate (&p3, &p2, 1.5, &q);
if (graphene_point_near (&p, &q, 0.001))
{
gsk_path_builder_quad_to (self, p.x, p.y, x3, y3);
return;
}
self->flags &= ~GSK_PATH_FLAT;
/* At this point, we are dealing with a cubic that can't be reduced to
* lines or quadratics. Check for cusps.
*/
{
GskCurve c, c1, c2, c3, c4;
float t[2];
int n;
gsk_curve_init_foreach (&c,
GSK_PATH_CUBIC,
(const graphene_point_t[]) { p0, p1, p2, p3 },
4,
0.f);
n = gsk_curve_get_cusps (&c, t);
if (n == 1)
{
gsk_curve_split (&c, t[0], &c1, &c2);
gsk_path_builder_append_current (self,
GSK_PATH_CUBIC,
3, &c1.cubic.points[1]);
gsk_path_builder_append_current (self,
GSK_PATH_QUAD,
2, (graphene_point_t[2]) { c1.cubic.points[3], c1.cubic.points[3] });
gsk_path_builder_append_current (self,
GSK_PATH_CUBIC,
3, &c2.cubic.points[1]);
return;
}
else if (n == 2)
{
if (t[1] < t[0])
{
float s = t[0];
t[0] = t[1];
t[1] = s;
}
gsk_curve_split (&c, t[0], &c1, &c2);
gsk_curve_split (&c2, (t[1] - t[0]) / (1 - t[0]), &c3, &c4);
gsk_path_builder_append_current (self,
GSK_PATH_CUBIC,
3, &c1.cubic.points[1]);
gsk_path_builder_append_current (self,
GSK_PATH_QUAD,
2, (graphene_point_t[2]) { c1.cubic.points[3], c1.cubic.points[3] });
gsk_path_builder_append_current (self,
GSK_PATH_CUBIC,
3, &c3.cubic.points[1]);
gsk_path_builder_append_current (self,
GSK_PATH_QUAD,
2, (graphene_point_t[2]) { c3.cubic.points[3], c3.cubic.points[3] });
gsk_path_builder_append_current (self,
GSK_PATH_CUBIC,
3, &c4.cubic.points[1]);
return;
}
}
gsk_path_builder_append_current (self,
GSK_PATH_CUBIC,
3, (graphene_point_t[3]) {
GRAPHENE_POINT_INIT (x1, y1),
GRAPHENE_POINT_INIT (x2, y2),
GRAPHENE_POINT_INIT (x3, y3)
});
3, (graphene_point_t[3]) { p1, p2, p3 });
}
/**
@@ -894,9 +1057,54 @@ gsk_path_builder_conic_to (GskPathBuilder *self,
float y2,
float weight)
{
graphene_point_t p0 = self->current_point;
graphene_point_t p1 = GRAPHENE_POINT_INIT (x1, y1);
graphene_point_t p2 = GRAPHENE_POINT_INIT (x2, y2);
g_return_if_fail (self != NULL);
g_return_if_fail (weight > 0);
if (weight == 1)
{
gsk_path_builder_quad_to (self, x1, y1, x2, y2);
return;
}
if (collinear (&p0, &p1, &p2))
{
GskBoundingBox bb;
/* We simplify degenerate quads to one or two lines
* (two lines are needed if there's a cusp).
*/
if (!gsk_bounding_box_contains_point (gsk_bounding_box_init (&bb, &p0, &p2), &p1))
{
GskCurve c;
gsk_curve_init_foreach (&c, GSK_PATH_CONIC,
(const graphene_point_t []) { p0, p1, p2 },
3, weight);
gsk_curve_get_tight_bounds (&c, &bb);
for (int i = 0; i < 4; i++)
{
graphene_point_t q;
gsk_bounding_box_get_corner (&bb, i, &q);
if (graphene_point_equal (&p0, &q) ||
graphene_point_equal (&p2, &q))
{
gsk_bounding_box_get_corner (&bb, (i + 2) % 4, &q);
gsk_path_builder_line_to (self, q.x, q.y);
break;
}
}
}
gsk_path_builder_line_to (self, x2, y2);
return;
}
self->flags &= ~GSK_PATH_FLAT;
gsk_path_builder_append_current (self,
GSK_PATH_CONIC,
@@ -1473,8 +1681,6 @@ gsk_path_builder_add_segment (GskPathBuilder *self,
const GskPathPoint *start,
const GskPathPoint *end)
{
GskRealPathPoint *s = (GskRealPathPoint *) start;
GskRealPathPoint *e = (GskRealPathPoint *) end;
const GskContour *contour;
gsize n_contours = gsk_path_get_n_contours (path);
graphene_point_t current;
@@ -1482,51 +1688,49 @@ gsk_path_builder_add_segment (GskPathBuilder *self,
g_return_if_fail (self != NULL);
g_return_if_fail (path != NULL);
g_return_if_fail (start != NULL);
g_return_if_fail (end != NULL);
g_return_if_fail (s->contour < n_contours);
g_return_if_fail (e->contour < n_contours);
g_return_if_fail (gsk_path_point_valid (start, path));
g_return_if_fail (gsk_path_point_valid (end, path));
current = self->current_point;
contour = gsk_path_get_contour (path, s->contour);
contour = gsk_path_get_contour (path, start->contour);
n_ops = gsk_contour_get_n_ops (contour);
if (s->contour == e->contour)
if (start->contour == end->contour)
{
if (gsk_path_point_compare (start, end) < 0)
{
gsk_contour_add_segment (contour, self, TRUE, s, e);
gsk_contour_add_segment (contour, self, TRUE, start, end);
goto out;
}
else if (n_contours == 1)
{
if (n_ops > 1)
gsk_contour_add_segment (contour, self, TRUE,
s,
&(GskRealPathPoint) { s->contour, n_ops - 1, 1 });
start,
&GSK_PATH_POINT_INIT (start->contour, n_ops - 1, 1.f));
gsk_contour_add_segment (contour, self, n_ops <= 1,
&(GskRealPathPoint) { s->contour, 1, 0 },
e);
&GSK_PATH_POINT_INIT (start->contour, 1, 0.f),
end);
goto out;
}
}
if (n_ops > 1)
gsk_contour_add_segment (contour, self, TRUE,
s,
&(GskRealPathPoint) { s->contour, n_ops - 1, 1. });
start,
&GSK_PATH_POINT_INIT (start->contour, n_ops - 1, 1.f));
for (gsize i = (s->contour + 1) % n_contours; i != e->contour; i = (i + 1) % n_contours)
for (gsize i = (start->contour + 1) % n_contours; i != end->contour; i = (i + 1) % n_contours)
gsk_path_builder_add_contour (self, gsk_contour_dup (gsk_path_get_contour (path, i)));
contour = gsk_path_get_contour (path, e->contour);
contour = gsk_path_get_contour (path, end->contour);
n_ops = gsk_contour_get_n_ops (contour);
if (n_ops > 1)
gsk_contour_add_segment (contour, self, TRUE,
&(GskRealPathPoint) { e->contour, 1, 0 },
e);
&GSK_PATH_POINT_INIT (end->contour, 1, 0.f),
end);
out:
gsk_path_builder_end_current (self);
+12 -12
View File
@@ -23,6 +23,7 @@
#include "gskpathbuilder.h"
#include "gskpathpointprivate.h"
#include "gskcontourprivate.h"
#include "gskpathprivate.h"
/**
@@ -38,6 +39,8 @@
*
* A `GskPathMeasure` struct is a reference counted struct
* and should be treated as opaque.
*
* Since: 4.14
*/
typedef struct _GskContourMeasure GskContourMeasure;
@@ -256,7 +259,6 @@ gsk_path_measure_get_point (GskPathMeasure *self,
float distance,
GskPathPoint *result)
{
GskRealPathPoint *res = (GskRealPathPoint *) result;
gsize i;
const GskContour *contour;
@@ -282,8 +284,11 @@ gsk_path_measure_get_point (GskPathMeasure *self,
contour = gsk_path_get_contour (self->path, i);
gsk_contour_get_point (contour, self->measures[i].contour_data, distance, res);
res->contour = i;
gsk_contour_get_point (contour, self->measures[i].contour_data, distance, result);
g_assert (0 <= result->t && result->t <= 1);
result->contour = i;
return TRUE;
}
@@ -304,21 +309,16 @@ float
gsk_path_point_get_distance (const GskPathPoint *point,
GskPathMeasure *measure)
{
GskRealPathPoint *p = (GskRealPathPoint *)point;
const GskContour *contour;
float contour_offset = 0;
g_return_val_if_fail (point != NULL, 0);
g_return_val_if_fail (measure != NULL, 0);
g_return_val_if_fail (p->contour < measure->n_contours, 0);
contour = gsk_path_get_contour (measure->path, p->contour);
g_return_val_if_fail (gsk_path_point_valid (point, measure->path), 0);
for (gsize i = 0; i < measure->n_contours; i++)
{
if (contour == gsk_path_get_contour (measure->path, i))
return contour_offset + gsk_contour_get_distance (contour,
p,
if (i == point->contour)
return contour_offset + gsk_contour_get_distance (gsk_path_get_contour (measure->path, i),
point,
measure->measures[i].contour_data);
contour_offset += measure->measures[i].length;
+823
View File
@@ -0,0 +1,823 @@
/*
* Copyright © 2020 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#include "config.h"
#include "gskpathprivate.h"
#include "gskcurveprivate.h"
#include "gskpathbuilder.h"
#include "gskpathpoint.h"
#include "gskcontourprivate.h"
static void
skip_whitespace (const char **p)
{
while (g_ascii_isspace (**p))
(*p)++;
}
static void
skip_optional_comma (const char **p)
{
skip_whitespace (p);
if (**p == ',')
(*p)++;
}
static gboolean
parse_number (const char **p,
double *c)
{
char *e;
*c = g_ascii_strtod (*p, &e);
if (e == *p)
return FALSE;
*p = e;
skip_optional_comma (p);
return TRUE;
}
static gboolean
parse_coordinate (const char **p,
double *c)
{
return parse_number (p, c);
}
static gboolean
parse_coordinate_pair (const char **p,
double *x,
double *y)
{
double xx, yy;
const char *o = *p;
if (!parse_coordinate (p, &xx))
{
*p = o;
return FALSE;
}
if (!parse_coordinate (p, &yy))
{
*p = o;
return FALSE;
}
*x = xx;
*y = yy;
return TRUE;
}
static gboolean
parse_nonnegative_number (const char **p,
double *x)
{
const char *o = *p;
double n;
if (!parse_number (p, &n))
return FALSE;
if (n < 0)
{
*p = o;
return FALSE;
}
*x = n;
return TRUE;
}
/* This fixes a flaw in our use of strchr() below:
*
* If p already points at the end of the string,
* we misinterpret strchr ("xyz", *p) returning
* non-NULL to mean that we can increment p.
*
* But strchr() will return a pointer to the
* final NUL byte in this case, and we walk off
* the end of the string. Oops
*/
static inline char *
_strchr (const char *str,
int c)
{
if (c == 0)
return NULL;
else
return strchr (str, c);
}
static gboolean
parse_flag (const char **p,
gboolean *f)
{
skip_whitespace (p);
if (_strchr ("01", **p))
{
*f = **p == '1';
(*p)++;
skip_optional_comma (p);
return TRUE;
}
return FALSE;
}
static gboolean
parse_command (const char **p,
char *cmd)
{
char *s;
const char *allowed;
if (*cmd == 'X')
allowed = "mM";
else
allowed = "mMhHvVzZlLcCsStTqQaAoO";
skip_whitespace (p);
s = _strchr (allowed, **p);
if (s)
{
*cmd = *s;
(*p)++;
return TRUE;
}
return FALSE;
}
static gboolean
parse_string (const char **p,
const char *s)
{
int len = strlen (s);
if (strncmp (*p, s, len) != 0)
return FALSE;
(*p) += len;
return TRUE;
}
#define NEAR(x, y) (fabs ((x) - (y)) < 0.001)
static gboolean
is_rect (double x0, double y0,
double x1, double y1,
double x2, double y2,
double x3, double y3)
{
return NEAR (x0, x3) && NEAR (x1, x2) &&
NEAR (y0, y1) && NEAR (y2, y3) &&
x0 < x1 && y1 < y2;
}
static gboolean
is_line (double x0, double y0,
double x1, double y1,
double x2, double y2,
double x3, double y3)
{
if (NEAR (y0, y3))
return x0 <= x1 && x1 <= x2 && x2 <= x3 &&
NEAR (y0, y1) && NEAR (y0, y2) && NEAR (y0, y3);
else
return y0 <= y1 && y1 <= y2 && y2 <= y3 &&
NEAR (x0, x1) && NEAR (x0, x2) && NEAR (x0, x3);
}
static gboolean
parse_rectangle (const char **p,
double *x,
double *y,
double *w,
double *h)
{
const char *o = *p;
double w2;
if (parse_coordinate_pair (p, x, y) &&
parse_string (p, "h") &&
parse_coordinate (p, w) &&
parse_string (p, "v") &&
parse_coordinate (p, h) &&
parse_string (p, "h") &&
parse_coordinate (p, &w2) &&
parse_string (p, "z") &&
w2 == -*w && *w >= 0 && *h >= 0)
{
skip_whitespace (p);
return TRUE;
}
*p = o;
return FALSE;
}
static gboolean
parse_circle (const char **p,
double *cx,
double *cy,
double *r)
{
const char *o = *p;
double x0, y0, x1, y1, x2, y2, x3, y3;
double x4, y4, x5, y5, x6, y6, x7, y7;
double x8, y8, w0, w1, w2, w3;
double rr;
if (parse_coordinate_pair (p, &x0, &y0) &&
parse_string (p, "o") &&
parse_coordinate_pair (p, &x1, &y1) &&
parse_coordinate_pair (p, &x2, &y2) &&
parse_nonnegative_number (p, &w0) &&
parse_string (p, "o") &&
parse_coordinate_pair (p, &x3, &y3) &&
parse_coordinate_pair (p, &x4, &y4) &&
parse_nonnegative_number (p, &w1) &&
parse_string (p, "o") &&
parse_coordinate_pair (p, &x5, &y5) &&
parse_coordinate_pair (p, &x6, &y6) &&
parse_nonnegative_number (p, &w2) &&
parse_string (p, "o") &&
parse_coordinate_pair (p, &x7, &y7) &&
parse_coordinate_pair (p, &x8, &y8) &&
parse_nonnegative_number (p, &w3) &&
parse_string (p, "z"))
{
rr = y1;
if (x1 == 0 && y1 == rr &&
x2 == -rr && y2 == rr &&
x3 == -rr && y3 == 0 &&
x4 == -rr && y4 == -rr &&
x5 == 0 && y5 == -rr &&
x6 == rr && y6 == -rr &&
x7 == rr && y7 == 0 &&
x8 == rr && y8 == rr &&
NEAR (w0, M_SQRT1_2) && NEAR (w1, M_SQRT1_2) &&
NEAR (w2, M_SQRT1_2) && NEAR (w3, M_SQRT1_2))
{
*cx = x0 - rr;
*cy = y0;
*r = rr;
skip_whitespace (p);
return TRUE;
}
}
*p = o;
return FALSE;
}
static gboolean
parse_rounded_rect (const char **p,
GskRoundedRect *rr)
{
const char *o = *p;
double x0, y0, x1, y1, x2, y2, x3, y3;
double x4, y4, x5, y5, x6, y6, x7, y7;
double x8, y8, x9, y9, x10, y10, x11, y11;
double x12, y12, w0, w1, w2, w3;
if (parse_coordinate_pair (p, &x0, &y0) &&
parse_string (p, "L") &&
parse_coordinate_pair (p, &x1, &y1) &&
parse_string (p, "O") &&
parse_coordinate_pair (p, &x2, &y2) &&
parse_coordinate_pair (p, &x3, &y3) &&
parse_nonnegative_number (p, &w0) &&
parse_string (p, "L") &&
parse_coordinate_pair (p, &x4, &y4) &&
parse_string (p, "O") &&
parse_coordinate_pair (p, &x5, &y5) &&
parse_coordinate_pair (p, &x6, &y6) &&
parse_nonnegative_number (p, &w1) &&
parse_string (p, "L") &&
parse_coordinate_pair (p, &x7, &y7) &&
parse_string (p, "O") &&
parse_coordinate_pair (p, &x8, &y8) &&
parse_coordinate_pair (p, &x9, &y9) &&
parse_nonnegative_number (p, &w2) &&
parse_string (p, "L") &&
parse_coordinate_pair (p, &x10, &y10) &&
parse_string (p, "O") &&
parse_coordinate_pair (p, &x11, &y11) &&
parse_coordinate_pair (p, &x12, &y12) &&
parse_nonnegative_number (p, &w3) &&
parse_string (p, "Z"))
{
if (NEAR (x0, x12) && NEAR (y0, y12) &&
is_rect (x11, y11, x2, y2, x5, y5, x8, y8) &&
is_line (x11, y11, x0, y0, x1, y1, x2, y2) &&
is_line (x2, y2, x3, y3, x4, y4, x5, y5) &&
is_line (x8, y8, x7, y7, x6, y6, x5, y5) &&
is_line (x11, y11, x10, y10, x9, y9, x8, y8) &&
NEAR (w0, M_SQRT1_2) && NEAR (w1, M_SQRT1_2) &&
NEAR (w2, M_SQRT1_2) && NEAR (w3, M_SQRT1_2))
{
rr->bounds = GRAPHENE_RECT_INIT (x11, y11, x5 - x11, y5 - y11);
rr->corner[GSK_CORNER_TOP_LEFT] = GRAPHENE_SIZE_INIT (x12 - x11, y10 - y11);
rr->corner[GSK_CORNER_TOP_RIGHT] = GRAPHENE_SIZE_INIT (x2 - x1, y3 - y2);
rr->corner[GSK_CORNER_BOTTOM_RIGHT] = GRAPHENE_SIZE_INIT (x5 - x6, y5 - y4);
rr->corner[GSK_CORNER_BOTTOM_LEFT] = GRAPHENE_SIZE_INIT (x7 - x8, y8 - y9);
skip_whitespace (p);
return TRUE;
}
}
*p = o;
return FALSE;
}
#undef NEAR
/**
* gsk_path_parse:
* @string: a string
*
* This is a convenience function that constructs a `GskPath`
* from a serialized form.
*
* The string is expected to be in (a superset of)
* [SVG path syntax](https://www.w3.org/TR/SVG11/paths.html#PathData),
* as e.g. produced by [method@Gsk.Path.to_string].
*
* A high-level summary of the syntax:
*
* - `M x y` Move to `(x, y)`
* - `L x y` Add a line from the current point to `(x, y)`
* - `Q x1 y1 x2 y2` Add a quadratic Bézier from the current point to `(x2, y2)`, with control point `(x1, y1)`
* - `C x1 y1 x2 y2 x3 y3` Add a cubic Bézier from the current point to `(x3, y3)`, with control points `(x1, y1)` and `(x2, y2)`
* - `Z` Close the contour by drawing a line back to the start point
* - `H x` Add a horizontal line from the current point to the given x value
* - `V y` Add a vertical line from the current point to the given y value
* - `T x2 y2` Add a quadratic Bézier, using the reflection of the previous segments' control point as control point
* - `S x2 y2 x3 y3` Add a cubic Bézier, using the reflection of the previous segments' second control point as first control point
* - `A rx ry r l s x y` Add an elliptical arc from the current point to `(x, y)` with radii rx and ry. See the SVG documentation for how the other parameters influence the arc.
* - `O x1 y1 x2 y2 w` Add a rational quadratic Bézier from the current point to `(x2, y2)` with control point `(x1, y1)` and weight `w`.
*
* All the commands have lowercase variants that interpret coordinates
* relative to the current point.
*
* The `O` command is an extension that is not supported in SVG.
*
* Returns: (nullable): a new `GskPath`, or `NULL` if @string could not be parsed
*
* Since: 4.14
*/
GskPath *
gsk_path_parse (const char *string)
{
GskPathBuilder *builder;
double x, y;
double prev_x1, prev_y1;
double path_x, path_y;
const char *p;
char cmd;
char prev_cmd;
gboolean after_comma;
gboolean repeat;
builder = gsk_path_builder_new ();
cmd = 'X';
path_x = path_y = 0;
x = y = 0;
prev_x1 = prev_y1 = 0;
after_comma = FALSE;
p = string;
while (*p)
{
prev_cmd = cmd;
repeat = !parse_command (&p, &cmd);
if (after_comma && !repeat)
goto error;
switch (cmd)
{
case 'X':
goto error;
case 'Z':
case 'z':
if (repeat)
goto error;
else
{
gsk_path_builder_close (builder);
x = path_x;
y = path_y;
}
break;
case 'M':
case 'm':
{
double x1, y1, w, h, r;
GskRoundedRect rr;
/* Look for special contours */
if (parse_rectangle (&p, &x1, &y1, &w, &h))
{
gsk_path_builder_add_rect (builder, &GRAPHENE_RECT_INIT (x1, y1, w, h));
if (_strchr ("zZX", prev_cmd))
{
path_x = x1;
path_y = y1;
}
x = x1;
y = y1;
}
else if (parse_circle (&p, &x1, &y1, &r))
{
gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (x1, y1), r);
if (_strchr ("zZX", prev_cmd))
{
path_x = x1 + r;
path_y = y1;
}
x = x1 + r;
y = y1;
}
else if (parse_rounded_rect (&p, &rr))
{
gsk_path_builder_add_rounded_rect (builder, &rr);
if (_strchr ("zZX", prev_cmd))
{
path_x = rr.bounds.origin.x + rr.corner[GSK_CORNER_TOP_LEFT].width;
path_y = rr.bounds.origin.y;
}
x = rr.bounds.origin.x + rr.corner[GSK_CORNER_TOP_LEFT].width;
y = rr.bounds.origin.y;
}
else if (parse_coordinate_pair (&p, &x1, &y1))
{
if (cmd == 'm')
{
x1 += x;
y1 += y;
}
if (repeat)
gsk_path_builder_line_to (builder, x1, y1);
else
{
gsk_path_builder_move_to (builder, x1, y1);
if (_strchr ("zZX", prev_cmd))
{
path_x = x1;
path_y = y1;
}
}
x = x1;
y = y1;
}
else
goto error;
}
break;
case 'L':
case 'l':
{
double x1, y1;
if (parse_coordinate_pair (&p, &x1, &y1))
{
if (cmd == 'l')
{
x1 += x;
y1 += y;
}
if (_strchr ("zZ", prev_cmd))
{
gsk_path_builder_move_to (builder, x, y);
path_x = x;
path_y = y;
}
gsk_path_builder_line_to (builder, x1, y1);
x = x1;
y = y1;
}
else
goto error;
}
break;
case 'H':
case 'h':
{
double x1;
if (parse_coordinate (&p, &x1))
{
if (cmd == 'h')
x1 += x;
if (_strchr ("zZ", prev_cmd))
{
gsk_path_builder_move_to (builder, x, y);
path_x = x;
path_y = y;
}
gsk_path_builder_line_to (builder, x1, y);
x = x1;
}
else
goto error;
}
break;
case 'V':
case 'v':
{
double y1;
if (parse_coordinate (&p, &y1))
{
if (cmd == 'v')
y1 += y;
if (_strchr ("zZ", prev_cmd))
{
gsk_path_builder_move_to (builder, x, y);
path_x = x;
path_y = y;
}
gsk_path_builder_line_to (builder, x, y1);
y = y1;
}
else
goto error;
}
break;
case 'C':
case 'c':
{
double x0, y0, x1, y1, x2, y2;
if (parse_coordinate_pair (&p, &x0, &y0) &&
parse_coordinate_pair (&p, &x1, &y1) &&
parse_coordinate_pair (&p, &x2, &y2))
{
if (cmd == 'c')
{
x0 += x;
y0 += y;
x1 += x;
y1 += y;
x2 += x;
y2 += y;
}
if (_strchr ("zZ", prev_cmd))
{
gsk_path_builder_move_to (builder, x, y);
path_x = x;
path_y = y;
}
gsk_path_builder_cubic_to (builder, x0, y0, x1, y1, x2, y2);
prev_x1 = x1;
prev_y1 = y1;
x = x2;
y = y2;
}
else
goto error;
}
break;
case 'S':
case 's':
{
double x0, y0, x1, y1, x2, y2;
if (parse_coordinate_pair (&p, &x1, &y1) &&
parse_coordinate_pair (&p, &x2, &y2))
{
if (cmd == 's')
{
x1 += x;
y1 += y;
x2 += x;
y2 += y;
}
if (_strchr ("CcSs", prev_cmd))
{
x0 = 2 * x - prev_x1;
y0 = 2 * y - prev_y1;
}
else
{
x0 = x;
y0 = y;
}
if (_strchr ("zZ", prev_cmd))
{
gsk_path_builder_move_to (builder, x, y);
path_x = x;
path_y = y;
}
gsk_path_builder_cubic_to (builder, x0, y0, x1, y1, x2, y2);
prev_x1 = x1;
prev_y1 = y1;
x = x2;
y = y2;
}
else
goto error;
}
break;
case 'Q':
case 'q':
{
double x1, y1, x2, y2;
if (parse_coordinate_pair (&p, &x1, &y1) &&
parse_coordinate_pair (&p, &x2, &y2))
{
if (cmd == 'q')
{
x1 += x;
y1 += y;
x2 += x;
y2 += y;
}
if (_strchr ("zZ", prev_cmd))
{
gsk_path_builder_move_to (builder, x, y);
path_x = x;
path_y = y;
}
gsk_path_builder_quad_to (builder, x1, y1, x2, y2);
prev_x1 = x1;
prev_y1 = y1;
x = x2;
y = y2;
}
else
goto error;
}
break;
case 'T':
case 't':
{
double x1, y1, x2, y2;
if (parse_coordinate_pair (&p, &x2, &y2))
{
if (cmd == 't')
{
x2 += x;
y2 += y;
}
if (_strchr ("QqTt", prev_cmd))
{
x1 = 2 * x - prev_x1;
y1 = 2 * y - prev_y1;
}
else
{
x1 = x;
y1 = y;
}
if (_strchr ("zZ", prev_cmd))
{
gsk_path_builder_move_to (builder, x, y);
path_x = x;
path_y = y;
}
gsk_path_builder_quad_to (builder, x1, y1, x2, y2);
prev_x1 = x1;
prev_y1 = y1;
x = x2;
y = y2;
}
else
goto error;
}
break;
case 'O':
case 'o':
{
double x1, y1, x2, y2, weight;
if (parse_coordinate_pair (&p, &x1, &y1) &&
parse_coordinate_pair (&p, &x2, &y2) &&
parse_nonnegative_number (&p, &weight))
{
if (cmd == 'o')
{
x1 += x;
y1 += y;
x2 += x;
y2 += y;
}
if (_strchr ("zZ", prev_cmd))
{
gsk_path_builder_move_to (builder, x, y);
path_x = x;
path_y = y;
}
gsk_path_builder_conic_to (builder, x1, y1, x2, y2, weight);
x = x2;
y = y2;
}
else
goto error;
}
break;
case 'A':
case 'a':
{
double rx, ry;
double x_axis_rotation;
int large_arc, sweep;
double x1, y1;
if (parse_nonnegative_number (&p, &rx) &&
parse_nonnegative_number (&p, &ry) &&
parse_number (&p, &x_axis_rotation) &&
parse_flag (&p, &large_arc) &&
parse_flag (&p, &sweep) &&
parse_coordinate_pair (&p, &x1, &y1))
{
if (cmd == 'a')
{
x1 += x;
y1 += y;
}
if (_strchr ("zZ", prev_cmd))
{
gsk_path_builder_move_to (builder, x, y);
path_x = x;
path_y = y;
}
gsk_path_builder_svg_arc_to (builder,
rx, ry, x_axis_rotation,
large_arc, sweep,
x1, y1);
x = x1;
y = y1;
}
else
goto error;
}
break;
default:
goto error;
}
after_comma = (p > string) && p[-1] == ',';
}
if (after_comma)
goto error;
return gsk_path_builder_free_to_path (builder);
error:
//g_warning ("Can't parse string '%s' as GskPath, error at %ld", string, p - string);
gsk_path_builder_unref (builder);
return NULL;
}
/* vim:set foldmethod=marker expandtab: */
+30 -42
View File
@@ -22,9 +22,7 @@
#include <math.h>
#include "gskpathpointprivate.h"
#include "gskcontourprivate.h"
#include "gdk/gdkprivate.h"
#define RAD_TO_DEG(x) ((x) / (G_PI / 180.f))
@@ -41,10 +39,10 @@
* [method@Gsk.Path.get_start_point], [method@Gsk.Path.get_end_point]
* or [method@Gsk.PathMeasure.get_point].
*
* Note that `GskPathPoint` structs are meant to be stack-allocated, and
* don't a reference to the path object they are obtained from. It is the
* callers responsibility to keep a reference to the path as long as the
* `GskPathPoint` is used.
* Note that `GskPathPoint` structs are meant to be stack-allocated,
* and don't hold a reference to the path object they are obtained from.
* It is the callers responsibility to keep a reference to the path
* as long as the `GskPathPoint` is used.
*
* Since: 4.14
*/
@@ -53,7 +51,6 @@ G_DEFINE_BOXED_TYPE (GskPathPoint, gsk_path_point,
gsk_path_point_copy,
gsk_path_point_free)
GskPathPoint *
gsk_path_point_copy (GskPathPoint *point)
{
@@ -61,7 +58,7 @@ gsk_path_point_copy (GskPathPoint *point)
copy = g_new0 (GskPathPoint, 1);
memcpy (copy, point, sizeof (GskRealPathPoint));
memcpy (copy, point, sizeof (GskPathPoint));
return copy;
}
@@ -94,14 +91,11 @@ gboolean
gsk_path_point_equal (const GskPathPoint *point1,
const GskPathPoint *point2)
{
const GskRealPathPoint *p1 = (const GskRealPathPoint *) point1;
const GskRealPathPoint *p2 = (const GskRealPathPoint *) point2;
if (p1->contour == p2->contour)
if (point1->contour == point2->contour)
{
if ((p1->idx == p2->idx && p1->t == p2->t) ||
(p1->idx + 1 == p2->idx && p1->t == 1 && p2->t == 0) ||
(p1->idx == p2->idx + 1 && p1->t == 0 && p2->t == 1))
if ((point1->idx == point2->idx && point1->t == point2->t) ||
(point1->idx + 1 == point2->idx && point1->t == 1 && point2->t == 0) ||
(point1->idx == point2->idx + 1 && point1->t == 0 && point2->t == 1))
return TRUE;
}
@@ -125,23 +119,20 @@ int
gsk_path_point_compare (const GskPathPoint *point1,
const GskPathPoint *point2)
{
const GskRealPathPoint *p1 = (const GskRealPathPoint *) point1;
const GskRealPathPoint *p2 = (const GskRealPathPoint *) point2;
if (gsk_path_point_equal (point1, point2))
return 0;
if (p1->contour < p2->contour)
if (point1->contour < point2->contour)
return -1;
else if (p1->contour > p2->contour)
else if (point1->contour > point2->contour)
return 1;
else if (p1->idx < p2->idx)
else if (point1->idx < point2->idx)
return -1;
else if (p1->idx > p2->idx)
else if (point1->idx > point2->idx)
return 1;
else if (p1->t < p2->t)
else if (point1->t < point2->t)
return -1;
else if (p1->t > p2->t)
else if (point1->t > point2->t)
return 1;
return 0;
@@ -163,16 +154,14 @@ gsk_path_point_get_position (const GskPathPoint *point,
GskPath *path,
graphene_point_t *position)
{
GskRealPathPoint *self = (GskRealPathPoint *) point;
const GskContour *contour;
g_return_if_fail (self != NULL);
g_return_if_fail (path != NULL);
g_return_if_fail (gsk_path_point_valid (point, path));
g_return_if_fail (position != NULL);
g_return_if_fail (self->contour < gsk_path_get_n_contours (path));
contour = gsk_path_get_contour (path, self->contour),
gsk_contour_get_position (contour, self, position);
contour = gsk_path_get_contour (path, point->contour),
gsk_contour_get_position (contour, point, position);
}
/**
@@ -191,6 +180,9 @@ gsk_path_point_get_position (const GskPathPoint *point,
* point, and the direction coming out of it. The @direction
* argument lets you choose which one to get.
*
* If the path is just a single point (e.g. a circle with
* radius zero), then @tangent is set to `0, 0`.
*
* If you want to orient something in the direction of the
* path, [method@Gsk.PathPoint.get_rotation] may be more
* convenient to use.
@@ -203,16 +195,14 @@ gsk_path_point_get_tangent (const GskPathPoint *point,
GskPathDirection direction,
graphene_vec2_t *tangent)
{
GskRealPathPoint *self = (GskRealPathPoint *) point;
const GskContour *contour;
g_return_if_fail (self != NULL);
g_return_if_fail (path != NULL);
g_return_if_fail (gsk_path_point_valid (point, path));
g_return_if_fail (tangent != NULL);
g_return_if_fail (self->contour < gsk_path_get_n_contours (path));
contour = gsk_path_get_contour (path, self->contour),
gsk_contour_get_tangent (contour, self, direction, tangent);
contour = gsk_path_get_contour (path, point->contour),
gsk_contour_get_tangent (contour, point, direction, tangent);
}
/**
@@ -237,12 +227,10 @@ gsk_path_point_get_rotation (const GskPathPoint *point,
GskPath *path,
GskPathDirection direction)
{
GskRealPathPoint *self = (GskRealPathPoint *) point;
graphene_vec2_t tangent;
g_return_val_if_fail (self != NULL, 0);
g_return_val_if_fail (path != NULL, 0);
g_return_val_if_fail (self->contour < gsk_path_get_n_contours (path), 0);
g_return_val_if_fail (gsk_path_point_valid (point, path), 0);
gsk_path_point_get_tangent (point, path, direction, &tangent);
@@ -266,6 +254,8 @@ gsk_path_point_get_rotation (const GskPathPoint *point,
* Lines have a curvature of zero (indicating an osculating circle of
* infinite radius. In this case, the @center is not modified.
*
* Circles with a radius of zero have `INFINITY` as curvature
*
* Note that certain points on a path may not have a single curvature,
* such as sharp turns. At such points, there are two curvatures --
* the (limit of) the curvature of the path going into the point,
@@ -287,13 +277,11 @@ gsk_path_point_get_curvature (const GskPathPoint *point,
GskPathDirection direction,
graphene_point_t *center)
{
GskRealPathPoint *self = (GskRealPathPoint *) point;
const GskContour *contour;
g_return_val_if_fail (self != NULL, 0);
g_return_val_if_fail (path != NULL, 0);
g_return_val_if_fail (self->contour < gsk_path_get_n_contours (path), 0);
g_return_val_if_fail (gsk_path_point_valid (point, path), 0);
contour = gsk_path_get_contour (path, self->contour);
return gsk_contour_get_curvature (contour, self, direction, center);
contour = gsk_path_get_contour (path, point->contour);
return gsk_contour_get_curvature (contour, point, direction, center);
}
+11 -4
View File
@@ -31,12 +31,19 @@ G_BEGIN_DECLS
#define GSK_TYPE_PATH_POINT (gsk_path_point_get_type ())
typedef struct _GskPathPoint GskPathPoint;
struct _GskPathPoint {
G_GNUC_EXTENSION struct _GskPathPoint
{
/*< private >*/
union {
float f[8];
gpointer p[8];
} data;
struct {
gsize contour;
gsize idx;
float t;
};
gpointer padding[8];
graphene_vec4_t alignment;
};
};
GDK_AVAILABLE_IN_4_14
+28 -7
View File
@@ -5,14 +5,35 @@
G_BEGIN_DECLS
struct _GskRealPathPoint
{
gsize contour;
gsize idx;
float t;
};
#define GSK_PATH_POINT_INIT(c,i,tt) ((GskPathPoint){ .contour=(c), .idx=(i), .t=(tt) })
G_STATIC_ASSERT (sizeof (GskRealPathPoint) <= sizeof (GskPathPoint));
static inline gboolean
gsk_path_point_valid (const GskPathPoint *point,
GskPath *path)
{
const GskContour *contour;
gsize n_ops;
if (point == NULL)
return FALSE;
if (path == NULL)
return TRUE;
if (point->contour >= gsk_path_get_n_contours (path))
return FALSE;
contour = gsk_path_get_contour (path, point->contour);
n_ops = gsk_contour_get_n_ops (contour);
if ((n_ops > 1 && point->idx >= n_ops) ||
(n_ops == 1 && point->idx > n_ops))
return FALSE;
if (point->t < 0 || point->t > 1)
return FALSE;
return TRUE;
}
G_END_DECLS
+46 -22
View File
@@ -248,6 +248,13 @@ gsk_linear_gradient_node_draw (GskRenderNode *node,
if (gsk_render_node_get_node_type (node) == GSK_REPEATING_LINEAR_GRADIENT_NODE)
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
if (self->stops[0].offset > 0.0)
cairo_pattern_add_color_stop_rgba (pattern,
0.0,
self->stops[0].color.red,
self->stops[0].color.green,
self->stops[0].color.blue,
self->stops[0].color.alpha);
for (i = 0; i < self->n_stops; i++)
{
cairo_pattern_add_color_stop_rgba (pattern,
@@ -257,6 +264,13 @@ gsk_linear_gradient_node_draw (GskRenderNode *node,
self->stops[i].color.blue,
self->stops[i].color.alpha);
}
if (self->stops[self->n_stops-1].offset < 1.0)
cairo_pattern_add_color_stop_rgba (pattern,
1.0,
self->stops[self->n_stops-1].color.red,
self->stops[self->n_stops-1].color.green,
self->stops[self->n_stops-1].color.blue,
self->stops[self->n_stops-1].color.alpha);
cairo_set_source (cr, pattern);
cairo_pattern_destroy (pattern);
@@ -562,13 +576,29 @@ gsk_radial_gradient_node_draw (GskRenderNode *node,
else
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
for (i = 0; i < self->n_stops; i++)
if (self->stops[0].offset > 0.0)
cairo_pattern_add_color_stop_rgba (pattern,
self->stops[i].offset,
self->stops[i].color.red,
self->stops[i].color.green,
self->stops[i].color.blue,
self->stops[i].color.alpha);
0.0,
self->stops[0].color.red,
self->stops[0].color.green,
self->stops[0].color.blue,
self->stops[0].color.alpha);
for (i = 0; i < self->n_stops; i++)
{
cairo_pattern_add_color_stop_rgba (pattern,
self->stops[i].offset,
self->stops[i].color.red,
self->stops[i].color.green,
self->stops[i].color.blue,
self->stops[i].color.alpha);
}
if (self->stops[self->n_stops-1].offset < 1.0)
cairo_pattern_add_color_stop_rgba (pattern,
1.0,
self->stops[self->n_stops-1].color.red,
self->stops[self->n_stops-1].color.green,
self->stops[self->n_stops-1].color.blue,
self->stops[self->n_stops-1].color.alpha);
gsk_cairo_rectangle (cr, &node->bounds);
cairo_translate (cr, self->center.x, self->center.y);
@@ -4822,18 +4852,8 @@ gsk_shadow_node_draw (GskRenderNode *node,
cairo_t *cr)
{
GskShadowNode *self = (GskShadowNode *) node;
cairo_pattern_t *pattern;
gsize i;
cairo_save (cr);
/* clip so the push_group() creates a small surface */
gsk_cairo_rectangle (cr, &self->child->bounds);
cairo_clip (cr);
cairo_push_group (cr);
gsk_render_node_draw (self->child, cr);
pattern = cairo_pop_group (cr);
cairo_restore (cr);
cairo_save (cr);
/* clip so the blur area stays small */
gsk_cairo_rectangle (cr, &node->bounds);
@@ -4842,27 +4862,31 @@ gsk_shadow_node_draw (GskRenderNode *node,
for (i = 0; i < self->n_shadows; i++)
{
GskShadow *shadow = &self->shadows[i];
cairo_pattern_t *pattern;
/* We don't need to draw invisible shadows */
if (gdk_rgba_is_clear (&shadow->color))
continue;
cairo_save (cr);
gdk_cairo_set_source_rgba (cr, &shadow->color);
cr = gsk_cairo_blur_start_drawing (cr, shadow->radius, GSK_BLUR_X | GSK_BLUR_Y);
cairo_save (cr);
cairo_translate (cr, shadow->dx, shadow->dy);
cairo_push_group (cr);
gsk_render_node_draw (self->child, cr);
pattern = cairo_pop_group (cr);
gdk_cairo_set_source_rgba (cr, &shadow->color);
cairo_mask (cr, pattern);
cairo_restore (cr);
cr = gsk_cairo_blur_finish_drawing (cr, shadow->radius, &shadow->color, GSK_BLUR_X | GSK_BLUR_Y);
cairo_restore (cr);
}
cairo_set_source (cr, pattern);
cairo_paint (cr);
cairo_restore (cr);
gsk_render_node_draw (self->child, cr);
cairo_pattern_destroy (pattern);
cairo_restore (cr);
}
static void
@@ -4983,7 +5007,7 @@ gsk_shadow_node_new (GskRenderNode *child,
self = gsk_render_node_alloc (GSK_SHADOW_NODE);
node = (GskRenderNode *) self;
node->offscreen_for_opacity = child->offscreen_for_opacity;
node->offscreen_for_opacity = TRUE;
self->child = gsk_render_node_ref (child);
self->n_shadows = n_shadows;
+1 -1
View File
@@ -3286,7 +3286,7 @@ gsk_text_node_serialize_glyphs (GskRenderNode *node,
string_append_double (p, (double) glyphs[i].geometry.y_offset / PANGO_SCALE);
if (!glyphs[i].attr.is_cluster_start)
g_string_append (p, " same-cluster");
if (!glyphs[i].attr.is_color)
if (glyphs[i].attr.is_color)
g_string_append (p, " color");
}
-2
View File
@@ -44,8 +44,6 @@ G_BEGIN_DECLS
GRAPHENE_SIZE_INIT(0, 0),\
}}
typedef struct _GskRoundedRect GskRoundedRect;
struct _GskRoundedRect
{
graphene_rect_t bounds;
-208
View File
@@ -1,208 +0,0 @@
/*
* Copyright © 2002 University of Southern California
* 2020 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
* Carl D. Worth <cworth@cworth.org>
*/
#include "config.h"
#include "gsksplineprivate.h"
#include <math.h>
/* Spline deviation from the circle in radius would be given by:
error = sqrt (x**2 + y**2) - 1
A simpler error function to work with is:
e = x**2 + y**2 - 1
From "Good approximation of circles by curvature-continuous Bezier
curves", Tor Dokken and Morten Daehlen, Computer Aided Geometric
Design 8 (1990) 22-41, we learn:
abs (max(e)) = 4/27 * sin**6(angle/4) / cos**2(angle/4)
and
abs (error) =~ 1/2 * e
Of course, this error value applies only for the particular spline
approximation that is used in _cairo_gstate_arc_segment.
*/
static float
arc_error_normalized (float angle)
{
return 2.0/27.0 * pow (sin (angle / 4), 6) / pow (cos (angle / 4), 2);
}
static float
arc_max_angle_for_tolerance_normalized (float tolerance)
{
float angle, error;
guint i;
/* Use table lookup to reduce search time in most cases. */
struct {
float angle;
float error;
} table[] = {
{ G_PI / 1.0, 0.0185185185185185036127 },
{ G_PI / 2.0, 0.000272567143730179811158 },
{ G_PI / 3.0, 2.38647043651461047433e-05 },
{ G_PI / 4.0, 4.2455377443222443279e-06 },
{ G_PI / 5.0, 1.11281001494389081528e-06 },
{ G_PI / 6.0, 3.72662000942734705475e-07 },
{ G_PI / 7.0, 1.47783685574284411325e-07 },
{ G_PI / 8.0, 6.63240432022601149057e-08 },
{ G_PI / 9.0, 3.2715520137536980553e-08 },
{ G_PI / 10.0, 1.73863223499021216974e-08 },
{ G_PI / 11.0, 9.81410988043554039085e-09 },
};
for (i = 0; i < G_N_ELEMENTS (table); i++)
{
if (table[i].error < tolerance)
return table[i].angle;
}
i++;
do {
angle = G_PI / i++;
error = arc_error_normalized (angle);
} while (error > tolerance);
return angle;
}
static guint
arc_segments_needed (float angle,
float radius,
float tolerance)
{
float max_angle;
/* the error is amplified by at most the length of the
* major axis of the circle; see cairo-pen.c for a more detailed analysis
* of this. */
max_angle = arc_max_angle_for_tolerance_normalized (tolerance / radius);
return ceil (fabs (angle) / max_angle);
}
/* We want to draw a single spline approximating a circular arc radius
R from angle A to angle B. Since we want a symmetric spline that
matches the endpoints of the arc in position and slope, we know
that the spline control points must be:
(R * cos(A), R * sin(A))
(R * cos(A) - h * sin(A), R * sin(A) + h * cos (A))
(R * cos(B) + h * sin(B), R * sin(B) - h * cos (B))
(R * cos(B), R * sin(B))
for some value of h.
"Approximation of circular arcs by cubic polynomials", Michael
Goldapp, Computer Aided Geometric Design 8 (1991) 227-238, provides
various values of h along with error analysis for each.
From that paper, a very practical value of h is:
h = 4/3 * R * tan(angle/4)
This value does not give the spline with minimal error, but it does
provide a very good approximation, (6th-order convergence), and the
error expression is quite simple, (see the comment for
_arc_error_normalized).
*/
static gboolean
gsk_spline_decompose_arc_segment (const graphene_point_t *center,
float radius,
float angle_A,
float angle_B,
GskSplineAddCurveFunc curve_func,
gpointer user_data)
{
float r_sin_A, r_cos_A;
float r_sin_B, r_cos_B;
float h;
r_sin_A = radius * sin (angle_A);
r_cos_A = radius * cos (angle_A);
r_sin_B = radius * sin (angle_B);
r_cos_B = radius * cos (angle_B);
h = 4.0/3.0 * tan ((angle_B - angle_A) / 4.0);
return curve_func ((graphene_point_t[4]) {
GRAPHENE_POINT_INIT (
center->x + r_cos_A,
center->y + r_sin_A
),
GRAPHENE_POINT_INIT (
center->x + r_cos_A - h * r_sin_A,
center->y + r_sin_A + h * r_cos_A
),
GRAPHENE_POINT_INIT (
center->x + r_cos_B + h * r_sin_B,
center->y + r_sin_B - h * r_cos_B
),
GRAPHENE_POINT_INIT (
center->x + r_cos_B,
center->y + r_sin_B
)
},
user_data);
}
gboolean
gsk_spline_decompose_arc (const graphene_point_t *center,
float radius,
float tolerance,
float start_angle,
float end_angle,
GskSplineAddCurveFunc curve_func,
gpointer user_data)
{
float step = start_angle - end_angle;
guint i, n_segments;
/* Recurse if drawing arc larger than pi */
if (ABS (step) > G_PI)
{
float mid_angle = (start_angle + end_angle) / 2.0;
return gsk_spline_decompose_arc (center, radius, tolerance, start_angle, mid_angle, curve_func, user_data)
&& gsk_spline_decompose_arc (center, radius, tolerance, mid_angle, end_angle, curve_func, user_data);
}
else if (ABS (step) < tolerance)
{
return gsk_spline_decompose_arc_segment (center, radius, start_angle, end_angle, curve_func, user_data);
}
n_segments = arc_segments_needed (ABS (step), radius, tolerance);
step = (end_angle - start_angle) / n_segments;
for (i = 0; i < n_segments - 1; i++, start_angle += step)
{
if (!gsk_spline_decompose_arc_segment (center, radius, start_angle, start_angle + step, curve_func, user_data))
return FALSE;
}
return gsk_spline_decompose_arc_segment (center, radius, start_angle, end_angle, curve_func, user_data);
}
-41
View File
@@ -1,41 +0,0 @@
/*
* Copyright © 2020 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#ifndef __GSK_SPLINE_PRIVATE_H__
#define __GSK_SPLINE_PRIVATE_H__
#include "gskpath.h"
G_BEGIN_DECLS
typedef gboolean (* GskSplineAddCurveFunc) (const graphene_point_t curve[4],
gpointer user_data);
gboolean gsk_spline_decompose_arc (const graphene_point_t *center,
float radius,
float tolerance,
float start_angle,
float end_angle,
GskSplineAddCurveFunc curve_func,
gpointer user_data);
G_END_DECLS
#endif /* __GSK_SPLINE_PRIVATE_H__ */
+1
View File
@@ -31,6 +31,7 @@ typedef struct _GskPathMeasure GskPathMeasure;
typedef struct _GskPathPoint GskPathPoint;
typedef struct _GskRenderer GskRenderer;
typedef struct _GskRenderNode GskRenderNode;
typedef struct _GskRoundedRect GskRoundedRect;
typedef struct _GskStroke GskStroke;
typedef struct _GskTransform GskTransform;
+1 -1
View File
@@ -29,6 +29,7 @@ gsk_public_sources = files([
'gskpath.c',
'gskpathbuilder.c',
'gskpathmeasure.c',
'gskpathparser.c',
'gskpathpoint.c',
'gskrenderer.c',
'gskrendernode.c',
@@ -47,7 +48,6 @@ gsk_private_sources = files([
'gskdebug.c',
'gskprivate.c',
'gskprofiler.c',
'gskspline.c',
'gl/gskglattachmentstate.c',
'gl/gskglbuffer.c',
'gl/gskglcommandqueue.c',
+1 -1
View File
@@ -18,7 +18,7 @@
#pragma once
#include <gdk/gdk.h>
#include <gsk/gskrenderer.h>
#include <gsk/gsk.h>
#ifdef GDK_RENDERING_VULKAN
+2
View File
@@ -58,6 +58,8 @@ rounded_rect_shrink (RoundedRect r, vec4 amount)
vec4 new_bounds = r.bounds + vec4(1.0,1.0,-1.0,-1.0) * amount.wxyz;
vec4 new_widths = max (r.corner_widths - sign (r.corner_widths) * amount.wyyw, 0.0);
vec4 new_heights = max (r.corner_heights - sign (r.corner_heights) * amount.xxzz, 0.0);
new_widths = min (new_widths, new_bounds.z - new_bounds.x);
new_heights = min (new_heights, new_bounds.w - new_bounds.y);
return RoundedRect (new_bounds, new_widths, new_heights);
}
+2 -8
View File
@@ -25,14 +25,8 @@ any license fees or royalties.</description>
<homepage rdf:resource="http://www.gtk.org/" />
<license rdf:resource="http://usefulinc.com/doap/licenses/lgpl" />
<bug-database rdf:resource="https://gitlab.gnome.org/GNOME/gtk/issues/" />
<download-page rdf:resource="http://download.gnome.org/sources/gtk+/" />
<mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/gtk-list" />
<mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list" />
<mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/gtk-devel-list" />
<mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/gtk-doc-list" />
<mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/gtk-i18n-list" />
<mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/gtk-perl-list" />
<mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/language-bindings" />
<download-page rdf:resource="https://download.gnome.org/sources/gtk/" />
<developer-forum rdf:resource="https://discourse.gnome.org/c/platform/5" />
<category rdf:resource="http://api.gnome.org/doap-extensions#core" />
<programming-language>C</programming-language>
+3
View File
@@ -290,6 +290,9 @@ gtk_color_button_init (GtkColorButton *button)
button->button = gtk_button_new ();
g_signal_connect (button->button, "clicked", G_CALLBACK (gtk_color_button_clicked), button);
g_object_bind_property (button, "focus-on-click",
button->button, "focus-on-click",
0);
gtk_widget_set_parent (button->button, GTK_WIDGET (button));
button->swatch = g_object_new (GTK_TYPE_COLOR_SWATCH,
+3
View File
@@ -594,6 +594,9 @@ gtk_font_button_init (GtkFontButton *font_button)
font_button->button = gtk_button_new ();
g_signal_connect (font_button->button, "clicked", G_CALLBACK (gtk_font_button_clicked), font_button);
g_object_bind_property (font_button, "focus-on-click",
font_button->button, "focus-on-click",
0);
font_button->font_label = gtk_label_new (_("Font"));
gtk_widget_set_hexpand (font_button->font_label, TRUE);
font_button->size_label = gtk_label_new ("14");
+2
View File
@@ -734,10 +734,12 @@ gtk_tree_model_filter_build_level (GtkTreeModelFilter *filter,
g_assert (filter->priv->child_model != NULL);
/* Avoid building a level that already exists */
#ifndef G_DISABLE_ASSERT
if (parent_level)
g_assert (parent_elt->children == NULL);
else
g_assert (filter->priv->root == NULL);
#endif
if (filter->priv->in_row_deleted)
return;
+4 -1
View File
@@ -12833,7 +12833,10 @@ gtk_tree_view_is_blank_at_pos (GtkTreeView *tree_view,
*column = real_column;
gtk_tree_model_get_iter (priv->model, &iter, real_path);
_gtk_tree_view_find_node (tree_view, real_path, &tree, &node);
if (!_gtk_tree_view_find_node (tree_view, real_path, &tree, &node))
{
g_assert_not_reached ();
}
/* Check if there's an expander arrow at (x, y) */
if (real_column == priv->expander_column
+1 -1
View File
@@ -26,7 +26,7 @@
/**
* GtkActionable:
*
* The `GtkActionable` interface provides a convenient way of asscociating
* The `GtkActionable` interface provides a convenient way of associating
* widgets with actions.
*
* It primarily consists of two properties: [property@Gtk.Actionable:action-name]
+17 -9
View File
@@ -282,6 +282,8 @@ gtk_center_layout_measure_opposite (GtkCenterLayout *self,
int total_nat, above_nat, below_nat;
GtkWidget *child[3];
GtkRequestedSize sizes[3];
gboolean have_baseline = FALSE;
gboolean align_baseline = FALSE;
int i;
child[0] = self->start_widget;
@@ -305,27 +307,33 @@ gtk_center_layout_measure_opposite (GtkCenterLayout *self,
&child_min, &child_nat,
&child_min_baseline, &child_nat_baseline);
if (child_min_baseline >= 0)
total_min = MAX (total_min, child_min);
total_nat = MAX (total_nat, child_nat);
if (orientation == GTK_ORIENTATION_VERTICAL && child_min_baseline >= 0)
{
have_baseline = TRUE;
if (gtk_widget_get_valign (child[i]) == GTK_ALIGN_BASELINE_FILL ||
gtk_widget_get_valign (child[i]) == GTK_ALIGN_BASELINE_CENTER)
align_baseline = TRUE;
below_min = MAX (below_min, child_min - child_min_baseline);
above_min = MAX (above_min, child_min_baseline);
below_nat = MAX (below_nat, child_nat - child_nat_baseline);
above_nat = MAX (above_nat, child_nat_baseline);
}
else
{
total_min = MAX (total_min, child_min);
total_nat = MAX (total_nat, child_nat);
}
}
if (above_min >= 0)
if (have_baseline)
{
int min_baseline = -1;
int nat_baseline = -1;
total_min = MAX (total_min, above_min + below_min);
total_nat = MAX (total_nat, above_nat + below_nat);
if (align_baseline)
{
total_min = MAX (total_min, above_min + below_min);
total_nat = MAX (total_nat, above_nat + below_nat);
}
switch (self->baseline_pos)
{
+32 -9
View File
@@ -231,7 +231,7 @@ parse_compose_sequence (const char *seq,
char *start = words[i];
char *end = strchr (words[i], '>');
char *match;
gunichar codepoint;
guint keyval;
if (words[i][0] == '\0')
continue;
@@ -248,18 +248,24 @@ parse_compose_sequence (const char *seq,
if (is_codepoint (match))
{
codepoint = (gunichar) g_ascii_strtoll (match + 1, NULL, 16);
sequence[n] = codepoint;
keyval = gdk_unicode_to_keyval ((gunichar) g_ascii_strtoll (match + 1, NULL, 16));
if (keyval > 0xffff)
g_warning ("Can't handle >16bit keyvals");
sequence[n] = (guint16) keyval;
sequence[n + 1] = 0;
}
else
{
codepoint = (gunichar) gdk_keyval_from_name (match);
sequence[n] = codepoint;
keyval = gdk_keyval_from_name (match);
if (keyval > 0xffff)
g_warning ("Can't handle >16bit keyvals");
sequence[n] = (guint16) keyval;
sequence[n + 1] = 0;
}
if (codepoint == GDK_KEY_VoidSymbol)
if (keyval == GDK_KEY_VoidSymbol)
g_warning ("Could not get code point of keysym %s", match);
g_free (match);
n++;
@@ -1331,11 +1337,28 @@ gtk_compose_table_check (const GtkComposeTable *table,
if (!seq_index)
return FALSE;
if (n_compose == 1)
return TRUE;
match = FALSE;
if (n_compose == 1)
{
if (seq_index[2] - seq_index[1] > 0)
{
seq = table->data + seq_index[1];
value = seq[0];
if ((value & (1 << 15)) != 0)
g_string_append (output, &table->char_data[value & ~(1 << 15)]);
else
g_string_append_unichar (output, value);
if (compose_match)
*compose_match = TRUE;
}
return TRUE;
}
for (i = n_compose - 1; i < table->max_seq_len; i++)
{
len = i + 1;
+3 -2
View File
@@ -30,12 +30,13 @@ typedef struct _GtkComposeTableCompact GtkComposeTableCompact;
* The first part of the data contains rows of length max_seq_len + 1,
* where the first element is the item of the sequence, and the
* following elements are offsets to the data for sequences that
* start with the first item of length 2, ..., max_seq_len.
* start with the first item of length 1, ..., max_seq_len.
*
* The second part of the data contains the rest of the sequence
* data. It does not have a fixed stride. For each sequence, we
* put seq[2], ..., seq[len - 1], followed by the encoded value
* for this sequence.
* for this sequence. In particular for a sequence of length 1,
* the offset points directly to the value.
*
* The values are encoded as follows:
*
+14 -3
View File
@@ -266,7 +266,8 @@ static int
gtk_css_filter_value_compute_matrix (const GtkCssValue *value,
int first,
graphene_matrix_t *matrix,
graphene_vec4_t *offset)
graphene_vec4_t *offset,
gboolean *all_opacity)
{
graphene_matrix_t m, m2;
graphene_vec4_t o, o2;
@@ -275,11 +276,14 @@ gtk_css_filter_value_compute_matrix (const GtkCssValue *value,
if (!gtk_css_filter_get_matrix (&value->filters[first], matrix, offset))
return first;
*all_opacity = value->filters[first].type == GTK_CSS_FILTER_OPACITY;
for (i = first + 1; i < value->n_filters; i++)
{
if (!gtk_css_filter_get_matrix (&value->filters[i], &m, &o))
return i;
*all_opacity &= value->filters[i].type == GTK_CSS_FILTER_OPACITY;
graphene_matrix_multiply (matrix, &m, &m2);
graphene_matrix_transform_vec4 (&m, offset, &o2);
@@ -936,6 +940,7 @@ gtk_css_filter_value_push_snapshot (const GtkCssValue *filter,
{
graphene_matrix_t matrix;
graphene_vec4_t offset;
gboolean all_opacity;
int i, j;
if (gtk_css_filter_value_is_none (filter))
@@ -944,9 +949,15 @@ gtk_css_filter_value_push_snapshot (const GtkCssValue *filter,
i = 0;
while (i < filter->n_filters)
{
j = gtk_css_filter_value_compute_matrix (filter, i, &matrix, &offset);
j = gtk_css_filter_value_compute_matrix (filter, i, &matrix, &offset, &all_opacity);
if (i < j)
gtk_snapshot_push_color_matrix (snapshot, &matrix, &offset);
{
if (all_opacity)
gtk_snapshot_push_opacity (snapshot, graphene_matrix_get_value (&matrix, 3, 3));
else
gtk_snapshot_push_color_matrix (snapshot, &matrix, &offset);
}
if (j < filter->n_filters)
{
+13 -1
View File
@@ -1646,14 +1646,18 @@ gtk_entry_measure (GtkWidget *widget,
{
GtkEntry *entry = GTK_ENTRY (widget);
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
int text_min, text_nat;
int i;
gtk_widget_measure (priv->text,
orientation,
for_size,
minimum, natural,
&text_min, &text_nat,
minimum_baseline, natural_baseline);
*minimum = text_min;
*natural = text_nat;
for (i = 0; i < MAX_ICONS; i++)
{
EntryIconInfo *icon_info = priv->icons[i];
@@ -1691,6 +1695,14 @@ gtk_entry_measure (GtkWidget *widget,
*minimum = MAX (*minimum, prog_min);
*natural = MAX (*natural, prog_nat);
}
if (orientation == GTK_ORIENTATION_VERTICAL)
{
if (G_LIKELY (*minimum_baseline >= 0))
*minimum_baseline += (*minimum - text_min) / 2;
if (G_LIKELY (*natural_baseline >= 0))
*natural_baseline += (*natural - text_nat) / 2;
}
}
static void
+4 -4
View File
@@ -23,11 +23,11 @@
#include "gtkprivate.h"
#include "gtkbinlayout.h"
#include "gtkcolumnviewcell.h"
#include "gtkdragsource.h"
#include "gtkgestureclick.h"
#include "gtkgesturelongpress.h"
#include "gtkicontheme.h"
#include "gtklistitem.h"
#include "gtkselectionmodel.h"
#include "gtkfilechooserutils.h"
#include "gtkfilechooserwidgetprivate.h"
@@ -37,7 +37,7 @@ struct _GtkFileChooserCell
GtkWidget parent_instance;
GFileInfo *item;
GtkColumnViewCell *list_item;
GtkListItem *list_item;
};
struct _GtkFileChooserCellClass
@@ -75,7 +75,7 @@ popup_menu (GtkFileChooserCell *self,
if (self->list_item)
gtk_widget_activate_action (widget, "item.popup-file-list-menu",
"(udd)", gtk_column_view_cell_get_position (self->list_item), p.x, p.y);
"(udd)", gtk_list_item_get_position (self->list_item), p.x, p.y);
}
static void
@@ -121,7 +121,7 @@ drag_prepare_cb (GtkDragSource *source,
impl = GTK_FILE_CHOOSER_WIDGET (gtk_widget_get_ancestor (GTK_WIDGET (self),
GTK_TYPE_FILE_CHOOSER_WIDGET));
if (self->list_item && !gtk_column_view_cell_get_selected (self->list_item))
if (self->list_item && !gtk_list_item_get_selected (self->list_item))
{
gtk_widget_activate_action (GTK_WIDGET (self), "listitem.select", "(bb)", FALSE, FALSE);
}
+34 -71
View File
@@ -328,8 +328,6 @@ struct _GtkFileChooserWidget
guint sort_directories_first : 1;
guint show_time : 1;
guint shortcuts_current_folder_active : 1;
guint show_size_column : 1;
guint show_type_column : 1;
guint create_folders : 1;
guint auto_selecting_first_row : 1;
guint browse_files_interaction_frozen : 1;
@@ -1421,36 +1419,6 @@ change_show_hidden_state (GSimpleAction *action,
set_show_hidden (impl, g_variant_get_boolean (state));
}
/* Callback used when the "Show Size Column" menu item is toggled */
static void
change_show_size_state (GSimpleAction *action,
GVariant *state,
gpointer data)
{
GtkFileChooserWidget *impl = data;
g_simple_action_set_state (action, state);
impl->show_size_column = g_variant_get_boolean (state);
gtk_column_view_column_set_visible (impl->column_view_size_column,
impl->show_size_column);
}
/* Callback used when the "Show Type Column" menu item is toggled */
static void
change_show_type_state (GSimpleAction *action,
GVariant *state,
gpointer data)
{
GtkFileChooserWidget *impl = data;
g_simple_action_set_state (action, state);
impl->show_type_column = g_variant_get_boolean (state);
gtk_column_view_column_set_visible (impl->column_view_type_column,
impl->show_type_column);
}
static void
change_sort_directories_first_state (GSimpleAction *action,
GVariant *state,
@@ -1774,8 +1742,6 @@ static GActionEntry entries[] = {
{ "trash", trash_file_cb, NULL, NULL, NULL },
{ "popup-file-list-menu", popup_file_list_menu, "(udd)", NULL, NULL },
{ "toggle-show-hidden", NULL, NULL, "false", change_show_hidden_state },
{ "toggle-show-size", NULL, NULL, "false", change_show_size_state },
{ "toggle-show-type", NULL, NULL, "false", change_show_type_state },
{ "toggle-show-time", NULL, NULL, "false", change_show_time_state },
{ "toggle-sort-dirs-first", NULL, NULL, "false", change_sort_directories_first_state },
{ "toggle-view", toggle_view_cb, NULL, NULL, NULL },
@@ -1829,21 +1795,6 @@ file_list_build_popover (GtkFileChooserWidget *impl)
g_menu_append_item (section, item);
g_object_unref (item);
item = g_menu_item_new (_("Show _Size Column"), "item.toggle-show-size");
g_menu_item_set_attribute (item, "hidden-when", "s", "action-disabled");
g_menu_append_item (section, item);
g_object_unref (item);
item = g_menu_item_new (_("Show T_ype Column"), "item.toggle-show-type");
g_menu_item_set_attribute (item, "hidden-when", "s", "action-disabled");
g_menu_append_item (section, item);
g_object_unref (item);
item = g_menu_item_new (_("Show _Time"), "item.toggle-show-time");
g_menu_item_set_attribute (item, "hidden-when", "s", "action-disabled");
g_menu_append_item (section, item);
g_object_unref (item);
item = g_menu_item_new (_("Sort _Folders Before Files"), "item.toggle-sort-dirs-first");
g_menu_append_item (section, item);
g_object_unref (item);
@@ -1892,16 +1843,7 @@ file_list_update_popover (GtkFileChooserWidget *impl)
action = g_action_map_lookup_action (G_ACTION_MAP (impl->item_actions), "toggle-show-hidden");
g_simple_action_set_state (G_SIMPLE_ACTION (action), g_variant_new_boolean (impl->show_hidden));
action = g_action_map_lookup_action (G_ACTION_MAP (impl->item_actions), "toggle-show-size");
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), (impl->view_type == VIEW_TYPE_LIST));
g_simple_action_set_state (G_SIMPLE_ACTION (action), g_variant_new_boolean (impl->show_size_column));
action = g_action_map_lookup_action (G_ACTION_MAP (impl->item_actions), "toggle-show-type");
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), (impl->view_type == VIEW_TYPE_LIST));
g_simple_action_set_state (G_SIMPLE_ACTION (action), g_variant_new_boolean (impl->show_type_column));
action = g_action_map_lookup_action (G_ACTION_MAP (impl->item_actions), "toggle-show-time");
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), (impl->view_type == VIEW_TYPE_LIST));
g_simple_action_set_state (G_SIMPLE_ACTION (action), g_variant_new_boolean (impl->show_time));
action = g_action_map_lookup_action (G_ACTION_MAP (impl->item_actions), "toggle-sort-dirs-first");
@@ -3178,8 +3120,6 @@ static void
settings_load (GtkFileChooserWidget *impl)
{
gboolean show_hidden;
gboolean show_size_column;
gboolean show_type_column;
gboolean sort_directories_first;
DateFormat date_format;
TypeFormat type_format;
@@ -3193,8 +3133,6 @@ settings_load (GtkFileChooserWidget *impl)
settings = _gtk_file_chooser_get_settings_for_widget (GTK_WIDGET (impl));
show_hidden = g_settings_get_boolean (settings, SETTINGS_KEY_SHOW_HIDDEN);
show_size_column = g_settings_get_boolean (settings, SETTINGS_KEY_SHOW_SIZE_COLUMN);
show_type_column = g_settings_get_boolean (settings, SETTINGS_KEY_SHOW_TYPE_COLUMN);
sort_column = g_settings_get_enum (settings, SETTINGS_KEY_SORT_COLUMN);
sort_order = g_settings_get_enum (settings, SETTINGS_KEY_SORT_ORDER);
sidebar_width = g_settings_get_int (settings, SETTINGS_KEY_SIDEBAR_WIDTH);
@@ -3206,10 +3144,8 @@ settings_load (GtkFileChooserWidget *impl)
set_show_hidden (impl, show_hidden);
impl->show_size_column = show_size_column;
gtk_column_view_column_set_visible (impl->column_view_size_column, show_size_column);
impl->show_type_column = show_type_column;
gtk_column_view_column_set_visible (impl->column_view_type_column, show_type_column);
g_settings_bind (settings, SETTINGS_KEY_SHOW_SIZE_COLUMN, impl->column_view_size_column, "visible", G_SETTINGS_BIND_DEFAULT);
g_settings_bind (settings, SETTINGS_KEY_SHOW_TYPE_COLUMN, impl->column_view_type_column, "visible", G_SETTINGS_BIND_DEFAULT);
impl->sort_column = sort_column;
impl->sort_order = sort_order;
@@ -3248,8 +3184,6 @@ settings_save (GtkFileChooserWidget *impl)
g_settings_set_enum (settings, SETTINGS_KEY_LOCATION_MODE, impl->location_mode);
g_settings_set_boolean (settings, SETTINGS_KEY_SHOW_HIDDEN, impl->show_hidden);
g_settings_set_boolean (settings, SETTINGS_KEY_SHOW_SIZE_COLUMN, impl->show_size_column);
g_settings_set_boolean (settings, SETTINGS_KEY_SHOW_TYPE_COLUMN, impl->show_type_column);
g_settings_set_boolean (settings, SETTINGS_KEY_SORT_DIRECTORIES_FIRST, impl->sort_directories_first);
g_settings_set_enum (settings, SETTINGS_KEY_SORT_COLUMN, impl->sort_column);
g_settings_set_enum (settings, SETTINGS_KEY_SORT_ORDER, impl->sort_order);
@@ -3600,7 +3534,8 @@ show_and_select_files (GtkFileChooserWidget *impl,
if (info2 == info)
{
gtk_selection_model_select_item (impl->selection_model, i, FALSE);
gtk_column_view_scroll_to (GTK_COLUMN_VIEW (impl->browse_files_column_view), i, FALSE,
GTK_LIST_SCROLL_SELECT | GTK_LIST_SCROLL_FOCUS, FALSE);
g_clear_object (&info2);
selected_a_file = TRUE;
break;
@@ -6867,6 +6802,7 @@ post_process_ui (GtkFileChooserWidget *impl)
GtkShortcutTrigger *trigger;
GtkShortcutAction *action;
GtkShortcut *shortcut;
GAction *gaction;
target = gtk_drop_target_new (GDK_TYPE_FILE_LIST, GDK_ACTION_COPY | GDK_ACTION_MOVE);
g_signal_connect (target, "drop", G_CALLBACK (file_list_drag_drop_cb), impl);
@@ -6883,6 +6819,12 @@ post_process_ui (GtkFileChooserWidget *impl)
g_action_map_add_action_entries (G_ACTION_MAP (impl->item_actions),
entries, G_N_ELEMENTS (entries),
impl);
gaction = G_ACTION (g_property_action_new ("toggle-show-size", impl->column_view_size_column, "visible"));
g_action_map_add_action (G_ACTION_MAP (impl->item_actions), gaction);
g_object_unref (gaction);
gaction = G_ACTION (g_property_action_new ("toggle-show-type", impl->column_view_type_column, "visible"));
g_action_map_add_action (G_ACTION_MAP (impl->item_actions), gaction);
g_object_unref (gaction);
gtk_widget_insert_action_group (GTK_WIDGET (impl),
"item",
impl->item_actions);
@@ -7402,6 +7344,22 @@ setup_columns (GtkColumnView *view,
GtkFileChooserWidget *impl)
{
GtkListItemFactory *factory;
GMenu *menu;
GMenuItem *item;
menu = g_menu_new ();
item = g_menu_item_new (_("_Size"), "item.toggle-show-size");
g_menu_append_item (menu, item);
g_object_unref (item);
item = g_menu_item_new (_("T_ype"), "item.toggle-show-type");
g_menu_append_item (menu, item);
g_object_unref (item);
item = g_menu_item_new (_("_Time"), "item.toggle-show-time");
g_menu_append_item (menu, item);
g_object_unref (item);
factory = gtk_signal_list_item_factory_new ();
g_signal_connect_swapped (factory, "bind", G_CALLBACK (bind_name_cell), impl);
@@ -7409,6 +7367,7 @@ setup_columns (GtkColumnView *view,
gtk_column_view_column_set_expand (impl->column_view_name_column, TRUE);
gtk_column_view_column_set_resizable (impl->column_view_name_column, TRUE);
gtk_column_view_append_column (view, impl->column_view_name_column);
gtk_column_view_column_set_header_menu (impl->column_view_name_column, G_MENU_MODEL (menu));
factory = gtk_signal_list_item_factory_new ();
g_signal_connect_swapped (factory, "bind", G_CALLBACK (bind_location_cell), impl);
@@ -7417,22 +7376,28 @@ setup_columns (GtkColumnView *view,
gtk_column_view_column_set_resizable (impl->column_view_location_column, TRUE);
gtk_column_view_column_set_visible (impl->column_view_location_column, FALSE);
gtk_column_view_append_column (view, impl->column_view_location_column);
gtk_column_view_column_set_header_menu (impl->column_view_location_column, G_MENU_MODEL (menu));
factory = gtk_signal_list_item_factory_new ();
g_signal_connect_swapped (factory, "bind", G_CALLBACK (bind_size_cell), impl);
impl->column_view_size_column = gtk_column_view_column_new (_("Size"), factory);
gtk_column_view_append_column (view, impl->column_view_size_column);
gtk_column_view_column_set_header_menu (impl->column_view_size_column, G_MENU_MODEL (menu));
factory = gtk_signal_list_item_factory_new ();
g_signal_connect_swapped (factory, "bind", G_CALLBACK (bind_type_cell), impl);
impl->column_view_type_column = gtk_column_view_column_new (_("Type"), factory);
gtk_column_view_column_set_resizable (impl->column_view_type_column, TRUE);
gtk_column_view_append_column (view, impl->column_view_type_column);
gtk_column_view_column_set_header_menu (impl->column_view_type_column, G_MENU_MODEL (menu));
factory = gtk_signal_list_item_factory_new ();
g_signal_connect_swapped (factory, "bind", G_CALLBACK (bind_time_cell), impl);
impl->column_view_time_column = gtk_column_view_column_new (_("Modified"), factory);
gtk_column_view_append_column (view, impl->column_view_time_column);
gtk_column_view_column_set_header_menu (impl->column_view_time_column, G_MENU_MODEL (menu));
g_object_unref (menu);
}
static void
@@ -7453,8 +7418,6 @@ gtk_file_chooser_widget_init (GtkFileChooserWidget *impl)
impl->select_multiple = FALSE;
impl->sort_directories_first = FALSE;
impl->show_hidden = FALSE;
impl->show_size_column = TRUE;
impl->show_type_column = TRUE;
impl->type_format = TYPE_FORMAT_MIME;
impl->load_state = LOAD_EMPTY;
impl->reload_state = RELOAD_EMPTY;
-5
View File
@@ -1191,11 +1191,6 @@ gtk_synthesize_crossing_events (GtkRoot *toplevel,
for (widget = new_target; widget; widget = _gtk_widget_get_parent (widget))
gtk_widget_stack_append (&target_array, g_object_ref (widget));
if (old_target && new_target)
ancestor = gtk_widget_common_ancestor (old_target, new_target);
else
ancestor = NULL;
crossing.direction = GTK_CROSSING_IN;
seen_ancestor = FALSE;
+28 -6
View File
@@ -560,12 +560,21 @@ static void
update_accessible_properties (GtkModelButton *button)
{
if (button->menu_name || button->popover)
gtk_accessible_update_property (GTK_ACCESSIBLE (button),
GTK_ACCESSIBLE_PROPERTY_HAS_POPUP, TRUE,
-1);
{
gtk_accessible_update_state (GTK_ACCESSIBLE (button),
GTK_ACCESSIBLE_STATE_EXPANDED, FALSE,
-1);
gtk_accessible_update_property (GTK_ACCESSIBLE (button),
GTK_ACCESSIBLE_PROPERTY_HAS_POPUP, TRUE,
-1);
}
else
gtk_accessible_reset_property (GTK_ACCESSIBLE (button),
GTK_ACCESSIBLE_PROPERTY_HAS_POPUP);
{
gtk_accessible_reset_property (GTK_ACCESSIBLE (button),
GTK_ACCESSIBLE_PROPERTY_HAS_POPUP);
gtk_accessible_reset_state (GTK_ACCESSIBLE (button),
GTK_ACCESSIBLE_STATE_EXPANDED);
}
if (button->popover)
gtk_accessible_update_relation (GTK_ACCESSIBLE (button),
@@ -1057,7 +1066,12 @@ switch_menu (GtkModelButton *button)
stack = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_STACK);
if (stack != NULL)
gtk_stack_set_visible_child_name (GTK_STACK (stack), button->menu_name);
{
gtk_stack_set_visible_child_name (GTK_STACK (stack), button->menu_name);
gtk_accessible_update_state (GTK_ACCESSIBLE (button),
GTK_ACCESSIBLE_STATE_EXPANDED, TRUE,
-1);
}
}
static void
@@ -1077,6 +1091,10 @@ gtk_model_button_clicked (GtkModelButton *self)
gtk_popover_popup (GTK_POPOVER (submenu));
gtk_popover_menu_set_open_submenu (menu, submenu);
gtk_popover_menu_set_parent_menu (GTK_POPOVER_MENU (submenu), GTK_WIDGET (menu));
gtk_accessible_update_state (GTK_ACCESSIBLE (self),
GTK_ACCESSIBLE_STATE_EXPANDED, TRUE,
-1);
}
else if (!self->keep_open)
{
@@ -1085,6 +1103,10 @@ gtk_model_button_clicked (GtkModelButton *self)
popover = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_POPOVER);
if (popover)
gtk_popover_popdown (GTK_POPOVER (popover));
gtk_accessible_update_state (GTK_ACCESSIBLE (self),
GTK_ACCESSIBLE_STATE_EXPANDED, FALSE,
-1);
}
if (self->action_helper)
+10 -1
View File
@@ -301,6 +301,7 @@ gtk_search_entry_measure (GtkWidget *widget,
int *natural_baseline)
{
GtkSearchEntry *entry = GTK_SEARCH_ENTRY (widget);
int text_min, text_nat;
int icon_min, icon_nat;
int spacing;
@@ -309,9 +310,12 @@ gtk_search_entry_measure (GtkWidget *widget,
gtk_widget_measure (entry->entry,
orientation,
for_size,
minimum, natural,
&text_min, &text_nat,
minimum_baseline, natural_baseline);
*minimum = text_min;
*natural = text_nat;
gtk_widget_measure (entry->search_icon,
GTK_ORIENTATION_HORIZONTAL,
-1,
@@ -344,6 +348,11 @@ gtk_search_entry_measure (GtkWidget *widget,
{
*minimum = MAX (*minimum, icon_min);
*natural = MAX (*natural, icon_nat);
if (G_LIKELY (*minimum_baseline >= 0))
*minimum_baseline += (*minimum - text_min) / 2;
if (G_LIKELY (*natural_baseline >= 0))
*natural_baseline += (*natural - text_nat) / 2;
}
}
+50 -12
View File
@@ -47,13 +47,13 @@
*
* ```
* switch
* label
* label
* image
* image
* slider
* ```
*
* `GtkSwitch` has four css nodes, the main node with the name switch and
* subnodes for the slider and the on and off labels. Neither of them is
* subnodes for the slider and the on and off images. Neither of them is
* using any style classes.
*
* # Accessibility
@@ -140,6 +140,16 @@ G_DEFINE_TYPE_WITH_CODE (GtkSwitch, gtk_switch, GTK_TYPE_WIDGET,
G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIONABLE,
gtk_switch_actionable_iface_init))
static gboolean
is_right_side (GtkWidget *widget,
gboolean active)
{
if (_gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
return active;
else
return !active;
}
static void
gtk_switch_end_toggle_animation (GtkSwitch *self)
{
@@ -156,16 +166,18 @@ gtk_switch_on_frame_clock_update (GtkWidget *widget,
gpointer user_data)
{
GtkSwitch *self = GTK_SWITCH (widget);
double progress;
gtk_progress_tracker_advance_frame (&self->tracker,
gdk_frame_clock_get_frame_time (clock));
if (gtk_progress_tracker_get_state (&self->tracker) != GTK_PROGRESS_STATE_AFTER)
{
if (self->is_active)
self->handle_pos = 1.0 - gtk_progress_tracker_get_ease_out_cubic (&self->tracker, FALSE);
progress = gtk_progress_tracker_get_ease_out_cubic (&self->tracker, FALSE);
if (is_right_side (widget, self->is_active))
self->handle_pos = 1.0 - progress;
else
self->handle_pos = gtk_progress_tracker_get_ease_out_cubic (&self->tracker, FALSE);
self->handle_pos = progress;
}
else
{
@@ -251,7 +263,7 @@ gtk_switch_pan_gesture_pan (GtkGesturePan *gesture,
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
if (self->is_active)
if (is_right_side (widget, self->is_active))
offset += width / 2;
offset /= width / 2;
@@ -268,6 +280,7 @@ gtk_switch_pan_gesture_drag_end (GtkGestureDrag *gesture,
double y,
GtkSwitch *self)
{
GtkWidget *widget = GTK_WIDGET (self);
GdkEventSequence *sequence;
gboolean active;
@@ -278,16 +291,19 @@ gtk_switch_pan_gesture_drag_end (GtkGestureDrag *gesture,
/* if half the handle passed the middle of the switch, then we
* consider it to be on
*/
active = self->handle_pos >= 0.5;
if (_gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
active = self->handle_pos >= 0.5;
else
active = self->handle_pos <= 0.5;
}
else if (!gtk_gesture_handles_sequence (self->click_gesture, sequence))
active = self->is_active;
else
return;
self->handle_pos = active ? 1.0 : 0.0;
self->handle_pos = is_right_side (widget, active) ? 1.0 : 0.0;
gtk_switch_set_active (self, active);
gtk_widget_queue_allocate (GTK_WIDGET (self));
gtk_widget_queue_allocate (widget);
}
static void
@@ -354,6 +370,8 @@ gtk_switch_allocate (GtkWidget *widget,
/* Center ON icon in left half */
gtk_widget_measure (self->on_image, GTK_ORIENTATION_HORIZONTAL, -1, &min, NULL, NULL, NULL);
child_alloc.x = ((width / 2) - min) / 2;
if (is_right_side (widget, FALSE))
child_alloc.x += width / 2;
child_alloc.width = min;
gtk_widget_measure (self->on_image, GTK_ORIENTATION_VERTICAL, min, &min, NULL, NULL, NULL);
child_alloc.y = (height - min) / 2;
@@ -362,7 +380,9 @@ gtk_switch_allocate (GtkWidget *widget,
/* Center OFF icon in right half */
gtk_widget_measure (self->off_image, GTK_ORIENTATION_HORIZONTAL, -1, &min, NULL, NULL, NULL);
child_alloc.x = (width / 2) + ((width / 2) - min) / 2;
child_alloc.x = ((width / 2) - min) / 2;
if (is_right_side (widget, TRUE))
child_alloc.x += width / 2;
child_alloc.width = min;
gtk_widget_measure (self->off_image, GTK_ORIENTATION_VERTICAL, min, &min, NULL, NULL, NULL);
child_alloc.y = (height - min) / 2;
@@ -370,6 +390,18 @@ gtk_switch_allocate (GtkWidget *widget,
gtk_widget_size_allocate (self->off_image, &child_alloc, -1);
}
static void
gtk_switch_direction_changed (GtkWidget *widget,
GtkTextDirection previous_dir)
{
GtkSwitch *self = GTK_SWITCH (widget);
self->handle_pos = 1.0 - self->handle_pos;
gtk_widget_queue_allocate (widget);
GTK_WIDGET_CLASS (gtk_switch_parent_class)->direction_changed (widget, previous_dir);
}
static void
gtk_switch_set_action_name (GtkActionable *actionable,
const char *action_name)
@@ -552,6 +584,8 @@ gtk_switch_class_init (GtkSwitchClass *klass)
g_object_class_install_properties (gobject_class, LAST_PROP, switch_props);
widget_class->direction_changed = gtk_switch_direction_changed;
klass->activate = gtk_switch_activate;
klass->state_set = state_set;
@@ -676,6 +710,10 @@ gtk_switch_init (GtkSwitch *self)
gtk_accessible_update_state (GTK_ACCESSIBLE (self),
GTK_ACCESSIBLE_STATE_CHECKED, FALSE,
-1);
if (is_right_side (GTK_WIDGET (self), FALSE))
self->handle_pos = 1.0;
else
self->handle_pos = 0.0;
}
/**
@@ -714,7 +752,7 @@ gtk_switch_set_active (GtkSwitch *self,
self->is_active = is_active;
if (self->is_active)
if (is_right_side (GTK_WIDGET (self), self->is_active))
self->handle_pos = 1.0;
else
self->handle_pos = 0.0;
+10 -8
View File
@@ -2745,6 +2745,16 @@ gtk_text_click_gesture_pressed (GtkGestureClick *gesture,
guint button;
int tmp_pos;
if (!gtk_widget_has_focus (widget))
{
if (!gtk_widget_get_focus_on_click (widget))
return;
priv->in_click = TRUE;
gtk_widget_grab_focus (widget);
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
priv->in_click = FALSE;
}
button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
current = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
event = gtk_gesture_get_last_event (GTK_GESTURE (gesture), current);
@@ -2753,14 +2763,6 @@ gtk_text_click_gesture_pressed (GtkGestureClick *gesture,
y = widget_y;
gtk_text_reset_blink_time (self);
if (!gtk_widget_has_focus (widget))
{
priv->in_click = TRUE;
gtk_widget_grab_focus (widget);
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
priv->in_click = FALSE;
}
tmp_pos = gtk_text_find_position (self, x);
if (gdk_event_triggers_context_menu (event))
+5 -2
View File
@@ -302,8 +302,8 @@ gtk_tooltip_set_icon_from_gicon (GtkTooltip *tooltip,
* Replaces the widget packed into the tooltip with
* @custom_widget. @custom_widget does not get destroyed when the tooltip goes
* away.
* By default a box with a `GtkImage` and `GtkLabel` is embedded in
* the tooltip, which can be configured using gtk_tooltip_set_markup()
* By default a box with a `GtkImage` and `GtkLabel` is embedded in
* the tooltip, which can be configured using gtk_tooltip_set_markup()
* and gtk_tooltip_set_icon().
*/
void
@@ -560,6 +560,9 @@ gtk_tooltip_run_requery (GtkWidget **widget,
{
GtkWidget *parent = gtk_widget_get_parent (*widget);
if (GTK_IS_NATIVE (*widget))
break;
if (parent)
{
graphene_point_t r = GRAPHENE_POINT_INIT (*x, *y);
+28 -9
View File
@@ -4364,16 +4364,16 @@ gtk_window_realize (GtkWidget *widget)
{
gtk_window_enable_csd (window);
if (priv->title_box == NULL)
{
priv->title_box = gtk_header_bar_new ();
gtk_widget_add_css_class (priv->title_box, "titlebar");
gtk_widget_add_css_class (priv->title_box, "default-decoration");
if (priv->title_box == NULL)
{
priv->title_box = gtk_header_bar_new ();
gtk_widget_add_css_class (priv->title_box, "titlebar");
gtk_widget_add_css_class (priv->title_box, "default-decoration");
gtk_widget_insert_before (priv->title_box, widget, NULL);
}
gtk_widget_insert_before (priv->title_box, widget, NULL);
}
update_window_actions (window);
update_window_actions (window);
}
}
@@ -6517,6 +6517,21 @@ gtk_window_update_pointer_focus (GtkWindow *window,
}
}
static void
clear_widget_active_state (GtkWidget *widget,
GtkWidget *topmost)
{
GtkWidget *w = widget;
while (w)
{
gtk_widget_set_active_state (w, FALSE);
if (w == topmost)
break;
w = _gtk_widget_get_parent (w);
}
}
void
gtk_window_update_pointer_focus_on_state_change (GtkWindow *window,
GtkWidget *widget)
@@ -6537,7 +6552,11 @@ gtk_window_update_pointer_focus_on_state_change (GtkWindow *window,
if (focus->grab_widget &&
(focus->grab_widget == widget ||
gtk_widget_is_ancestor (focus->grab_widget, widget)))
gtk_pointer_focus_set_implicit_grab (focus, NULL);
{
clear_widget_active_state (focus->grab_widget, widget);
gtk_pointer_focus_set_implicit_grab (focus,
gtk_widget_get_parent (widget));
}
if (GTK_WIDGET (focus->toplevel) == widget)
{
+6 -3
View File
@@ -797,9 +797,12 @@ font_changed (GObject *object, GParamSpec *pspec, gpointer data)
font_desc = g_value_get_boxed (&val);
block_controller (G_OBJECT (fb));
gtk_font_dialog_button_set_font_desc (fb, font_desc);
unblock_controller (G_OBJECT (fb));
if (font_desc != NULL)
{
block_controller (G_OBJECT (fb));
gtk_font_dialog_button_set_font_desc (fb, font_desc);
unblock_controller (G_OBJECT (fb));
}
g_value_unset (&val);
}
+10 -10
View File
@@ -259,39 +259,39 @@ spinner {
.large-title {
font-weight: 300;
font-size: 24pt;
font-size: 240%;
}
.title-1 {
font-weight: 800;
font-size: 20pt;
font-size: 200%;
}
.title-2 {
font-weight: 800;
font-size: 15pt;
font-size: 150%;
}
.title-3 {
font-weight: 700;
font-size: 15pt;
font-size: 150%;
}
.title-4 {
font-weight: 700;
font-size: 13pt;
font-size: 130%;
}
.heading {
font-weight: 700;
font-size: 11pt;
font-size: 110%;
}
.body {
font-weight: 400;
font-size: 11pt;
font-size: 110%;
}
.caption-heading {
font-weight: 700;
font-size: 9pt;
font-size: 90%;
}
.caption {
font-weight: 400;
font-size: 9pt;
font-size: 90%;
}
/****************
@@ -3592,7 +3592,7 @@ window.dialog.message { // Message Dialog styling
& label.title {
font-weight: 800;
font-size: 15pt;
font-size: 150%;
}
&.csd { // rounded bottom border styling for csd version
+4 -1
View File
@@ -25,6 +25,7 @@ epoxy_req = '>= 1.4'
cloudproviders_req = '>= 0.3.1'
xkbcommon_req = '>= 0.2.0'
sysprof_req = '>= 3.38.0'
vulkan_req = '>= 1.2'
fs = import('fs')
gnome = import('gnome')
@@ -605,7 +606,9 @@ endif
# Uses meson's custom vulkan dependency searching. Set the VULKAN_SDK env var
# to use a custom path for the Vulkan SDK. Bugs that are found with it should
# be reported upstream and fixed.
vulkan_dep = dependency('vulkan', required: get_option('vulkan'))
vulkan_dep = dependency('vulkan',
version: vulkan_req,
required: get_option('vulkan'))
glslc = find_program('glslc', required: get_option('vulkan'))
if vulkan_dep.found()
have_vulkan = true
+2
View File
@@ -429,6 +429,8 @@ tools/gtk-path-tool.c
tools/gtk-path-tool-decompose.c
tools/gtk-path-tool-info.c
tools/gtk-path-tool-render.c
tools/gtk-path-tool-restrict.c
tools/gtk-path-tool-reverse.c
tools/gtk-path-tool-show.c
tools/gtk-path-tool-utils.c
tools/gtk-rendernode-tool.c
+2
View File
@@ -37,6 +37,8 @@ demos/gtk-demo/main.ui
demos/gtk-demo/menus.ui
demos/gtk-demo/offscreen_window2.c
demos/gtk-demo/paint.c
demos/gtk-demo/path_text.ui
demos/gtk-demo/path_walk.ui
demos/gtk-demo/popover.ui
demos/gtk-demo/revealer.ui
demos/gtk-demo/scale.ui
+63 -124
View File
@@ -34,8 +34,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gtk+ 2.8.2\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gtk/-/issues/\n"
"POT-Creation-Date: 2023-08-05 10:34+0000\n"
"PO-Revision-Date: 2023-08-05 11:18+0100\n"
"POT-Creation-Date: 2023-08-26 02:30+0000\n"
"PO-Revision-Date: 2023-08-26 11:18+0100\n"
"Last-Translator: Jordi Mas i Hernàndez <jmas@softcatala.org>\n"
"Language-Team: Catalan <tradgnome@softcatala.org>\n"
"Language: ca\n"
@@ -161,7 +161,7 @@ msgstr "L'aplicació no admet API de %s"
#. translators: This is about OpenGL backend names, like
#. * "Trying to use X11 GLX, but EGL is already in use"
#: gdk/gdkglcontext.c:1863
#: gdk/gdkglcontext.c:1864
#, c-format
msgid "Trying to use %s, but %s is already in use"
msgstr "S'està intentant utilitzar %s, però ja s'està utilitzant %s"
@@ -596,7 +596,7 @@ msgstr "No s'ha pogut llegir les dades a la fila %d"
#: gdk/macos/gdkmacospasteboard.c:211 gdk/wayland/gdkclipboard-wayland.c:240
#: gdk/wayland/gdkdrop-wayland.c:207 gdk/wayland/gdkprimary-wayland.c:343
#: gdk/win32/gdkdrop-win32.c:1018 gdk/win32/gdkdrop-win32.c:1063
#: gdk/x11/gdkclipboard-x11.c:805 gdk/x11/gdkdrop-x11.c:235
#: gdk/x11/gdkclipboard-x11.c:807 gdk/x11/gdkdrop-x11.c:235
msgid "No compatible transfer format found"
msgstr "No s'ha trobat cap format de transferència compatible"
@@ -770,10 +770,9 @@ msgid "No GL implementation is available"
msgstr "No hi ha cap implementació GL disponible"
#: gdk/win32/gdkglcontext-win32-wgl.c:396
#, fuzzy, c-format
#| msgid "EGL version %d.%d is too old. GTK requires %d.%d"
#, c-format
msgid "WGL version %d.%d is too low, need at least %d.%d"
msgstr "La versió de l'EGL %d.%d és massa antiga. La GTK requereix %d.%d"
msgstr "La versió %d.%d de WGL és massa baixa, cal com a mínim %d.%d"
#: gdk/win32/gdkglcontext-win32-wgl.c:414
#, c-format
@@ -838,11 +837,11 @@ msgid_plural "Opening %d Items"
msgstr[0] "S'està obrint %d element"
msgstr[1] "S'estan obrint %d elements"
#: gdk/x11/gdkclipboard-x11.c:475
#: gdk/x11/gdkclipboard-x11.c:477
msgid "Clipboard manager could not store selection."
msgstr "El gestor de porta-retalls no ha pogut desar la selecció."
#: gdk/x11/gdkclipboard-x11.c:655
#: gdk/x11/gdkclipboard-x11.c:657
msgid "Cannot store clipboard. No clipboard manager is active."
msgstr ""
"No es pot emmagatzemar el porta-retalls. No està actiu el gestor del porta-"
@@ -1111,13 +1110,13 @@ msgid "Pick a Color"
msgstr "Trieu un color"
#: gtk/deprecated/gtkcolorbutton.c:502 gtk/gtkcolorchooserwidget.c:313
#: gtk/gtkcolordialogbutton.c:302
#: gtk/gtkcolordialogbutton.c:335
#, c-format
msgid "Red %d%%, Green %d%%, Blue %d%%, Alpha %d%%"
msgstr "Vermell %d%%, verd %d%%, blau %d%%, alfa %d%%"
#: gtk/deprecated/gtkcolorbutton.c:508 gtk/gtkcolorchooserwidget.c:319
#: gtk/gtkcolordialogbutton.c:308
#: gtk/gtkcolordialogbutton.c:341
#, c-format
msgid "Red %d%%, Green %d%%, Blue %d%%"
msgstr "Vermell %d%%, verd %d%%, blau %d%%"
@@ -1132,11 +1131,11 @@ msgid "Pick a Font"
msgstr "Trieu un tipus de lletra"
#: gtk/deprecated/gtkfontbutton.c:597 gtk/gtkfilechooserwidget.c:3871
#: gtk/gtkfontdialogbutton.c:115 gtk/inspector/visual.ui:169
#: gtk/gtkfontdialogbutton.c:126 gtk/inspector/visual.ui:169
msgid "Font"
msgstr "Tipus de lletra"
#: gtk/deprecated/gtkfontbutton.c:1152 gtk/gtkfontdialogbutton.c:614
#: gtk/deprecated/gtkfontbutton.c:1152 gtk/gtkfontdialogbutton.c:652
msgctxt "font"
msgid "None"
msgstr "Cap"
@@ -2109,7 +2108,7 @@ msgstr "Personalitzat"
#: gtk/gtkcolorchooserwidget.c:571
msgid "Add Color"
msgstr "Afegeix color"
msgstr "Afegeix un color"
#: gtk/gtkcolorchooserwidget.c:593
#, c-format
@@ -2274,7 +2273,7 @@ msgstr "_Obre"
msgid "_Save"
msgstr "_Desa"
#: gtk/gtkfilechoosernativequartz.c:340 gtk/ui/gtkfilechooserwidget.ui:288
#: gtk/gtkfilechoosernativequartz.c:344 gtk/ui/gtkfilechooserwidget.ui:288
msgid "Select which types of files are shown"
msgstr "Seleccioneu quins tipus de fitxers es mostren"
@@ -2347,7 +2346,7 @@ msgid "If you delete an item, it will be permanently lost."
msgstr "Si suprimiu un element, es perdrà definitivament."
#: gtk/gtkfilechooserwidget.c:1185 gtk/gtkfilechooserwidget.c:1815
#: gtk/gtklabel.c:5695 gtk/gtktext.c:6125 gtk/gtktextview.c:9018
#: gtk/gtklabel.c:5695 gtk/gtktext.c:6145 gtk/gtktextview.c:9018
msgid "_Delete"
msgstr "_Suprimeix"
@@ -2488,7 +2487,7 @@ msgstr "Programa"
msgid "Audio"
msgstr "Àudio"
#: gtk/gtkfilechooserwidget.c:3872 gtk/gtkfilefilter.c:1035
#: gtk/gtkfilechooserwidget.c:3872 gtk/gtkfilefilter.c:1032
msgid "Image"
msgstr "Imatge"
@@ -2599,7 +2598,7 @@ msgstr "Selecciona carpetes"
msgid "Select a Folder"
msgstr "Selecciona una carpeta"
#: gtk/gtkfilefilter.c:1048
#: gtk/gtkfilefilter.c:1045
msgid "Unspecified"
msgstr "No especificat"
@@ -2691,19 +2690,19 @@ msgstr "Tanca"
msgid "Close the infobar"
msgstr "Tanca la barra d'informació"
#: gtk/gtklabel.c:5692 gtk/gtktext.c:6113 gtk/gtktextview.c:9006
#: gtk/gtklabel.c:5692 gtk/gtktext.c:6133 gtk/gtktextview.c:9006
msgid "Cu_t"
msgstr "Re_talla"
#: gtk/gtklabel.c:5693 gtk/gtktext.c:6117 gtk/gtktextview.c:9010
#: gtk/gtklabel.c:5693 gtk/gtktext.c:6137 gtk/gtktextview.c:9010
msgid "_Copy"
msgstr "_Copia"
#: gtk/gtklabel.c:5694 gtk/gtktext.c:6121 gtk/gtktextview.c:9014
#: gtk/gtklabel.c:5694 gtk/gtktext.c:6141 gtk/gtktextview.c:9014
msgid "_Paste"
msgstr "_Enganxa"
#: gtk/gtklabel.c:5700 gtk/gtktext.c:6134 gtk/gtktextview.c:9039
#: gtk/gtklabel.c:5700 gtk/gtktext.c:6154 gtk/gtktextview.c:9039
msgid "Select _All"
msgstr "Seleccion_a-ho tot"
@@ -2913,7 +2912,7 @@ msgstr "Pestanya anterior"
msgid "Next tab"
msgstr "Pestanya següent"
#: gtk/gtknotebook.c:4331 gtk/gtknotebook.c:6539
#: gtk/gtknotebook.c:4331 gtk/gtknotebook.c:6541
#, c-format
msgid "Page %u"
msgstr "Pàgina %u"
@@ -3658,7 +3657,7 @@ msgctxt "accessibility"
msgid "Sidebar"
msgstr "Barra lateral"
#: gtk/gtktext.c:6139 gtk/gtktextview.c:9044
#: gtk/gtktext.c:6159 gtk/gtktextview.c:9044
msgid "Insert _Emoji"
msgstr "Insereix _emoji"
@@ -7204,20 +7203,7 @@ msgid "Cant close stream"
msgstr "No es pot tancar el flux"
#: tools/gtk-builder-tool.c:36
#, fuzzy, c-format
#| msgid ""
#| "Usage:\n"
#| " gtk-builder-tool [COMMAND] [OPTION…] FILE\n"
#| "\n"
#| "Perform various tasks on GtkBuilder .ui files.\n"
#| "\n"
#| "Commands:\n"
#| " validate Validate the file\n"
#| " simplify Simplify the file\n"
#| " enumerate List all named objects\n"
#| " preview Preview the file\n"
#| " screenshot Take a screenshot of the file\n"
#| "\n"
#, c-format
msgid ""
"Usage:\n"
" gtk4-builder-tool [COMMAND] [OPTION…] FILE\n"
@@ -7243,7 +7229,8 @@ msgstr ""
" simplify Simplifica el fitxer\n"
" enumerate Llista tots els objectes anomenats\n"
" preview Previsualitza el fitxer\n"
" screenshot Fes una captura de pantalla\n"
" render Fes una captura de pantalla del fitxer\n"
" screenshot Fes una captura de pantalla del fitxer\n"
"\n"
#: tools/gtk-builder-tool-enumerate.c:56 tools/gtk-builder-tool-preview.c:179
@@ -7288,10 +7275,9 @@ msgstr "Utilitza l'estil del fitxer CSS"
#: tools/gtk-builder-tool-screenshot.c:370
#: tools/gtk-builder-tool-validate.c:268 tools/gtk-rendernode-tool-show.c:109
#: tools/gtk-rendernode-tool-render.c:204
#, fuzzy, c-format
#| msgid "Could not initialize EGL display"
#, c-format
msgid "Could not initialize windowing system\n"
msgstr "No s'ha pogut inicialitzar la pantalla EGL"
msgstr "No s'ha pogut inicialitzar el sistema de finestres\n"
#: tools/gtk-builder-tool-preview.c:195
msgid "Preview the file."
@@ -7306,13 +7292,14 @@ msgid "No .ui file specified\n"
msgstr "No s'ha especificat un fitxer .ui\n"
#: tools/gtk-builder-tool-preview.c:214
#, fuzzy, c-format
#, c-format
#| msgid "Can only simplify a single .ui file without --replace\n"
msgid "Can only preview a single .ui file\n"
msgstr "Només es pot simplificar un únic fitxer .ui sense --replace\n"
msgstr "Només es pot previsualitzar un únic fitxer .ui\n"
#: tools/gtk-builder-tool-screenshot.c:238
#, c-format
#| msgid "No results found"
msgid "No object found\n"
msgstr "No s'ha trobat cap objecte\n"
@@ -7323,10 +7310,9 @@ msgstr "Els objectes del tipus %s no poden ser captura de pantalla\n"
# FIXME
#: tools/gtk-builder-tool-screenshot.c:298
#, fuzzy, c-format
#| msgid "Failed to write hash table\n"
#, c-format
msgid "Failed to take a screenshot\n"
msgstr "No s'ha pogut escriure la taula de resum\n"
msgstr "No s'ha pogut fer una captura de pantalla\n"
#: tools/gtk-builder-tool-screenshot.c:309
#, c-format
@@ -7345,10 +7331,9 @@ msgstr "Sortida escrita a %s.\n"
#: tools/gtk-builder-tool-screenshot.c:336
#: tools/gtk-rendernode-tool-render.c:176
#, fuzzy, c-format
#| msgid "Failed to open file %s : %s\n"
#, c-format
msgid "Failed to save %s: %s\n"
msgstr "No s'ha pogut obrir el fitxer %s: %s\n"
msgstr "No s'ha pogut desar %s: %s\n"
#: tools/gtk-builder-tool-screenshot.c:359
msgid "Screenshot only the named object"
@@ -7372,10 +7357,9 @@ msgid "Render a .ui file to an image."
msgstr "Renderitza un fitxer .ui a una imatge."
#: tools/gtk-builder-tool-screenshot.c:397
#, fuzzy, c-format
#| msgid "Can only simplify a single .ui file without --replace\n"
msgid "Can only render a single .ui file to a single output file\n"
msgstr "Només es pot simplificar un únic fitxer .ui sense --replace\n"
msgstr ""
"Només es pot renderitzar un únic fitxer .ui a un únic fitxer de sortida\n"
#: tools/gtk-builder-tool-simplify.c:444
#, c-format
@@ -7383,28 +7367,24 @@ msgid "%s:%d: Couldnt parse value for property '%s': %s\n"
msgstr "%s:%d: no s'ha pogut analitzar el valor per a la propietat «%s»: %s\n"
#: tools/gtk-builder-tool-simplify.c:658
#, c-format, fuzzy
#| msgid "%s:%d: %sproperty %s::%s not found\n"
#, c-format
msgid "Property %s not found"
msgstr "No s'ha trobat la propietat %s"
#: tools/gtk-builder-tool-simplify.c:661
#, c-format, fuzzy
#| msgid "%s:%d: %sproperty %s::%s not found\n"
#, c-format
msgid "Packing property %s not found"
msgstr "No s'ha trobat la propietat d'empaquetatge %s"
#: tools/gtk-builder-tool-simplify.c:664
#, fuzzy, c-format
#| msgid "%s:%d: %sproperty %s::%s not found\n"
#, c-format
msgid "Cell property %s not found"
msgstr "%s:%d: %sproperty %s::%s no s'ha trobat\n"
msgstr "No s'ha trobat la propietat de cel·la %s"
#: tools/gtk-builder-tool-simplify.c:667
#, fuzzy, c-format
#| msgid "%s:%d: %sproperty %s::%s not found\n"
#, c-format
msgid "Layout property %s not found"
msgstr "%s:%d: %sproperty %s::%s no s'ha trobat\n"
msgstr "No s'ha trobat la propietat de disposició %s"
#: tools/gtk-builder-tool-simplify.c:1397
#, c-format
@@ -7430,7 +7410,6 @@ msgstr "No s'ha pogut llegir «%s»: %s\n"
#: tools/gtk-builder-tool-simplify.c:2510
#, c-format
#| msgid "Failed to write %s: “%s”\n"
msgid "Failed to write “%s”: “%s”\n"
msgstr "No s'ha pogut escriure «%s»: «%s»\n"
@@ -7452,9 +7431,9 @@ msgid "Can only simplify a single .ui file without --replace\n"
msgstr "Només es pot simplificar un únic fitxer .ui sense --replace\n"
#: tools/gtk-builder-tool-validate.c:45
#, c-format, fuzzy
#, c-format
msgid "Failed to lookup template parent type %s\n"
msgstr "No s'ha pogut cercar el tipus pare de la plantilla %s"
msgstr "No s'ha pogut cercar el tipus pare de la plantilla %s\n"
#: tools/gtk-builder-tool-validate.c:123
msgid "Deprecated types:\n"
@@ -7529,20 +7508,7 @@ msgid "%s: error launching application: %s\n"
msgstr "%s: s'ha produït un error en executar l'aplicació: %s\n"
#: tools/gtk-rendernode-tool.c:35
#, fuzzy, c-format
#| msgid ""
#| "Usage:\n"
#| " gtk-builder-tool [COMMAND] [OPTION…] FILE\n"
#| "\n"
#| "Perform various tasks on GtkBuilder .ui files.\n"
#| "\n"
#| "Commands:\n"
#| " validate Validate the file\n"
#| " simplify Simplify the file\n"
#| " enumerate List all named objects\n"
#| " preview Preview the file\n"
#| " screenshot Take a screenshot of the file\n"
#| "\n"
#, c-format
msgid ""
"Usage:\n"
" gtk4-rendernode-tool [COMMAND] [OPTION…] FILE\n"
@@ -7556,16 +7522,14 @@ msgid ""
"\n"
msgstr ""
"Ús:\n"
" gtk-builder-tool [ORDRE] [OPCIONS…] FITXER\n"
" gtk4-rendernode-tool [ORDRE] [OPCIÓ...] FITXER\n"
"\n"
"Fes diverses tasques en fitxers GtkBuilder .ui.\n"
"Realitza diverses tasques als nodes de renderització GTK.\n"
"\n"
"Ordres:\n"
" validate Valida el fitxer\n"
" simplify Simplifica el fitxer\n"
" enumerate Llista tots els objectes anomenats\n"
" preview Previsualitza el fitxer\n"
" screenshot Fes una captura de pantalla\n"
" info Proporciona informació sobre el node\n"
" show Mostra el node\n"
" render Fes una captura de pantalla del node\n"
"\n"
#: tools/gtk-rendernode-tool-info.c:177
@@ -7594,44 +7558,39 @@ msgstr "Proporciona informació sobre el node de renderització."
#: tools/gtk-rendernode-tool-info.c:222 tools/gtk-rendernode-tool-show.c:130
#: tools/gtk-rendernode-tool-render.c:225
#, fuzzy, c-format
#| msgid "No .ui file specified\n"
#, c-format
msgid "No .node file specified\n"
msgstr "No s'ha especificat un fitxer .ui\n"
msgstr "No s'ha especificat un fitxer .node\n"
#: tools/gtk-rendernode-tool-info.c:228
#, fuzzy, c-format
#| msgid "Can only simplify a single .ui file without --replace\n"
#, c-format
msgid "Can only accept a single .node file\n"
msgstr "Només es pot simplificar un únic fitxer .ui sense --replace\n"
msgstr "Només es pot acceptar un únic fitxer .node\n"
#: tools/gtk-rendernode-tool-show.c:117
msgid "Show the render node."
msgstr "Mostra el node de renderització."
#: tools/gtk-rendernode-tool-show.c:136
#, fuzzy, c-format
#| msgid "Can only simplify a single .ui file without --replace\n"
#, c-format
msgid "Can only preview a single .node file\n"
msgstr "Només es pot simplificar un únic fitxer .ui sense --replace\n"
msgstr "Només es pot previsualitzar un únic fitxer .node\n"
#: tools/gtk-rendernode-tool-render.c:123
#, c-format, fuzzy
#, c-format
msgid ""
"File %s exists.\n"
"If you want to overwrite, specify the filename.\n"
msgstr ""
"El fitxer %s existeix.\n"
"Si voleu sobreescriure, especifiqueu el nom del fitxer."
"Si voleu sobreescriure, especifiqueu el nom del fitxer.\n"
#: tools/gtk-rendernode-tool-render.c:137
#, fuzzy, c-format
#| msgid "Failed to open file %s : %s\n"
#, c-format
msgid "Failed to generate SVG: %s\n"
msgstr "No s'ha pogut obrir el fitxer %s: %s\n"
msgstr "No s'ha pogut generar el SVG: %s\n"
#: tools/gtk-rendernode-tool-render.c:196
#, fuzzy
msgid "Renderer to use"
msgstr "Renderitzador a utilitzar"
@@ -7640,15 +7599,14 @@ msgid "RENDERER"
msgstr "RENDERITZADOR"
#: tools/gtk-rendernode-tool-render.c:212
#, fuzzy
msgid "Render a .node file to an image."
msgstr "Renderitza un fitxer .node a una imatge."
#: tools/gtk-rendernode-tool-render.c:231
#, c-format, fuzzy
#, c-format
msgid "Can only render a single .node file to a single output file\n"
msgstr ""
"Només es pot renderitzar un únic fitxer .node a un únic fitxer de sortida"
"Només es pot renderitzar un únic fitxer .node a un únic fitxer de sortida\n"
#: tools/gtk-rendernode-tool-utils.c:51
#, c-format
@@ -7762,22 +7720,3 @@ msgid ""
msgstr ""
"No hi ha el fitxer índex de tema a «%s».\n"
"Si realment voleu crear una memòria cau d'icones aquí, utilitzeu --ignore-theme-index.\n"
#~ msgid "Tab list"
#~ msgstr "Llista de pestanyes"
#~ msgid "Allocation"
#~ msgstr "Assignació"
#~ msgid "Show fps overlay"
#~ msgstr "Mostra la superposició fps"
#~ msgid "Simulate Touchscreen"
#~ msgstr "Simula una pantalla tàctil"
#~ msgid "Take a screenshot of the file."
#~ msgstr "Feu una captura de pantalla del fitxer."
#, c-format
#~ msgid "Cant parse “%s”\n"
#~ msgstr "No es pot analitzar «%s»\n"
+1122 -654
View File
File diff suppressed because it is too large Load Diff
+1183 -876
View File
File diff suppressed because it is too large Load Diff
+329 -322
View File
File diff suppressed because it is too large Load Diff
+67 -34
View File
@@ -20,8 +20,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gtk+-master-po-gl-77922___.merged\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gtk/-/issues/\n"
"POT-Creation-Date: 2023-08-23 19:17+0000\n"
"PO-Revision-Date: 2023-08-24 08:19+0200\n"
"POT-Creation-Date: 2023-08-28 15:54+0000\n"
"PO-Revision-Date: 2023-08-29 00:36+0200\n"
"Last-Translator: Fran Dieguez <frandieguez@gnome.org>\n"
"Language-Team: Galician <proxecto@trasno.gal>\n"
"Language: gl\n"
@@ -2896,7 +2896,7 @@ msgstr "Anterior lapela"
msgid "Next tab"
msgstr "Seguinte lapela"
#: gtk/gtknotebook.c:4331 gtk/gtknotebook.c:6539
#: gtk/gtknotebook.c:4331 gtk/gtknotebook.c:6541
#, c-format
msgid "Page %u"
msgstr "Páxina %u"
@@ -3565,7 +3565,7 @@ msgctxt "keyboard side marker"
msgid "R"
msgstr "D"
#: gtk/gtkshortcutssection.c:407
#: gtk/gtkshortcutssection.c:414
msgid "_Show All"
msgstr "_Mostrar todos"
@@ -3602,27 +3602,27 @@ msgid "Swipe right"
msgstr "Deslizar á dereita"
#. Translators: This is placeholder text for the search entry in the shortcuts window
#: gtk/gtkshortcutswindow.c:855 gtk/gtkshortcutswindow.c:922
#: gtk/gtkshortcutswindow.c:927
#: gtk/gtkshortcutswindow.c:879 gtk/gtkshortcutswindow.c:946
#: gtk/gtkshortcutswindow.c:951
msgid "Search Shortcuts"
msgstr "Atallos da busca"
#. Translators: This is the window title for the shortcuts window in normal mode
#: gtk/gtkshortcutswindow.c:887 gtk/inspector/window.ui:498
#: gtk/gtkshortcutswindow.c:911 gtk/inspector/window.ui:498
msgid "Shortcuts"
msgstr "Atallos"
#. Translators: This is the window title for the shortcuts window in search mode
#: gtk/gtkshortcutswindow.c:892
#: gtk/gtkshortcutswindow.c:916
msgid "Search Results"
msgstr "Resultados da busca"
#: gtk/gtkshortcutswindow.c:989 gtk/ui/gtkemojichooser.ui:349
#: gtk/gtkshortcutswindow.c:1013 gtk/ui/gtkemojichooser.ui:349
#: gtk/ui/gtkfilechooserwidget.ui:239
msgid "No Results Found"
msgstr "Non se atopou ningún resultado"
#: gtk/gtkshortcutswindow.c:1000 gtk/ui/gtkemojichooser.ui:362
#: gtk/gtkshortcutswindow.c:1024 gtk/ui/gtkemojichooser.ui:362
#: gtk/ui/gtkfilechooserwidget.ui:252 gtk/ui/gtkplacesview.ui:218
msgid "Try a different search"
msgstr "Tente unha busca diferente"
@@ -3697,7 +3697,7 @@ msgid "Description"
msgstr "Descrición"
#: gtk/inspector/a11y.ui:99 gtk/inspector/misc-info.ui:296
#: tools/gtk-path-tool-info.c:133
#: tools/gtk-path-tool-info.c:132
msgid "Bounds"
msgstr "Limiares"
@@ -7482,95 +7482,105 @@ msgid ""
"\n"
"Commands:\n"
" decompose Decompose the path\n"
" reverse Reverse the path\n"
" restrict Restrict the path to a segment\n"
" show Display the path in a window\n"
" render Render the path as an image\n"
" info Print information about the path\n"
"\n"
msgstr ""
"Uso:\n"
" gtk4-path-tool [ORDE] FICHEIRO\n"
" gtk4-path-tool [ORDE] [OPCIÓN…] FICHEIRO\n"
"\n"
"Leva a cabo varias tarefas en rutas.\n"
"\n"
"Ordes:\n"
"\n"
" decompose Descompoñer a ruta\n"
" reverse Reverter a ruta\n"
"\n"
" restrict Restrinxir a ruta dun segmento\n"
" show Mostra a ruta nunha xanela\n"
" render Renderiza a ruta como unha imaxe\n"
"\n"
" info Fornece información da ruta\n"
"\n"
#: tools/gtk-path-tool-decompose.c:80
#: tools/gtk-path-tool-decompose.c:84
msgid "Allow quadratic Bézier curves"
msgstr "Permitir curvas Bézier cuadráticas"
#: tools/gtk-path-tool-decompose.c:81
#: tools/gtk-path-tool-decompose.c:85
msgid "Allow cubic Bézier curves"
msgstr "Permitir curvas Bézier cúbicas"
#: tools/gtk-path-tool-decompose.c:82
msgid "Allow elliptical arcs"
msgstr "Permitir arcos elípticos"
#: tools/gtk-path-tool-decompose.c:86
msgid "Allow conic Bézier curves"
msgstr "Permitir curvas Bézier cónicas"
#: tools/gtk-path-tool-decompose.c:83 tools/gtk-path-tool-info.c:93
#: tools/gtk-path-tool-render.c:58 tools/gtk-path-tool-show.c:127
#: tools/gtk-path-tool-decompose.c:87 tools/gtk-path-tool-info.c:88
#: tools/gtk-path-tool-render.c:58 tools/gtk-path-tool-restrict.c:38
#: tools/gtk-path-tool-show.c:127
msgid "PATH"
msgstr "RUTA"
#: tools/gtk-path-tool-decompose.c:95
#: tools/gtk-path-tool-decompose.c:99
msgid "Decompose a path."
msgstr "Descompoñer unha ruta."
#: tools/gtk-path-tool-decompose.c:108 tools/gtk-path-tool-info.c:117
#: tools/gtk-path-tool-decompose.c:112 tools/gtk-path-tool-info.c:113
#: tools/gtk-path-tool-restrict.c:64
msgid "No paths given."
msgstr "Non se forneceron rutas."
#: tools/gtk-path-tool-decompose.c:136
#: tools/gtk-path-tool-decompose.c:140 tools/gtk-path-tool-restrict.c:94
msgid "That didn't work out."
msgstr "Iso non funcionou."
#: tools/gtk-path-tool-info.c:104
#: tools/gtk-path-tool-info.c:100
msgid "Print information about a path."
msgstr "Mostra a información sobre a ruta."
#: tools/gtk-path-tool-info.c:124
#: tools/gtk-path-tool-info.c:121
msgid "Path is empty."
msgstr "A ruta está baleira."
#: tools/gtk-path-tool-info.c:130
#: tools/gtk-path-tool-info.c:127
msgid "Path is closed"
msgstr "A ruta está pechada"
#: tools/gtk-path-tool-info.c:139
#: tools/gtk-path-tool-info.c:129
msgid "Path length"
msgstr "Lonxitude da ruta"
#: tools/gtk-path-tool-info.c:138
#, c-format
msgid "%d contours"
msgstr "%d contornos"
#: tools/gtk-path-tool-info.c:141
#: tools/gtk-path-tool-info.c:140
#, c-format
msgid "%d operations"
msgstr "%d operacións"
#: tools/gtk-path-tool-info.c:145
#: tools/gtk-path-tool-info.c:144
#, c-format
msgid "%d lines"
msgstr "%d liñas"
#: tools/gtk-path-tool-info.c:150
#: tools/gtk-path-tool-info.c:149
#, c-format
msgid "%d quadratics"
msgstr "%d cuadráticas"
#: tools/gtk-path-tool-info.c:155
#: tools/gtk-path-tool-info.c:154
#, c-format
msgid "%d cubics"
msgstr "%d cúbicas"
#: tools/gtk-path-tool-info.c:160
#: tools/gtk-path-tool-info.c:159
#, c-format
msgid "%d arcs"
msgstr "%d arcos"
msgid "%d conics"
msgstr "%d cónicas"
#: tools/gtk-path-tool-render.c:53 tools/gtk-path-tool-show.c:123
msgid "Fill the path (the default)"
@@ -7694,6 +7704,22 @@ msgstr "Fallou o gardado do png en «%s»"
msgid "Output written to '%s'."
msgstr "Saída escrita en «%s»."
#: tools/gtk-path-tool-restrict.c:36
msgid "Beginning of segment"
msgstr "Comezo do segmento"
#: tools/gtk-path-tool-restrict.c:36 tools/gtk-path-tool-restrict.c:37
msgid "LENGTH"
msgstr "LONXITUDE"
#: tools/gtk-path-tool-restrict.c:37
msgid "End of segment"
msgstr "Final do segmento"
#: tools/gtk-path-tool-restrict.c:51
msgid "Restrict a path to a segment."
msgstr "Restrinxir unha ruta a unha segmento."
#: tools/gtk-path-tool-show.c:43 tools/gtk-path-tool-show.c:78
msgid "Path Preview"
msgstr "Vista previa"
@@ -7949,5 +7975,12 @@ msgstr ""
"Se está seguro de que quere crear unha caché de iconas aquí, use --ignore-"
"theme-index.\n"
#~ msgid "Allow elliptical arcs"
#~ msgstr "Permitir arcos elípticos"
#, c-format
#~ msgid "%d arcs"
#~ msgstr "%d arcos"
#~ msgid "Stroke the path instead of filling it"
#~ msgstr "Traza a ruta en lugar de enchela"
+2057 -1450
View File
File diff suppressed because it is too large Load Diff
+104 -61
View File
@@ -11,8 +11,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gtk\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gtk/-/issues/\n"
"POT-Creation-Date: 2023-08-22 16:19+0000\n"
"PO-Revision-Date: 2023-08-22 23:12+0200\n"
"POT-Creation-Date: 2023-08-31 12:06+0000\n"
"PO-Revision-Date: 2023-09-02 05:25+0200\n"
"Last-Translator: Ekaterine Papava <papava.e@gtu.ge>\n"
"Language-Team: Georgian <http://mail.gnome.org/mailman/listinfo/gnome-ge-"
"list>\n"
@@ -2879,7 +2879,7 @@ msgstr "_წინა ჩანართი"
msgid "Next tab"
msgstr "_შემდეგი ჩანართი"
#: gtk/gtknotebook.c:4331 gtk/gtknotebook.c:6539
#: gtk/gtknotebook.c:4331 gtk/gtknotebook.c:6541
#, c-format
msgid "Page %u"
msgstr "გვერდი %u"
@@ -3546,7 +3546,7 @@ msgctxt "keyboard side marker"
msgid "R"
msgstr "მარჯ"
#: gtk/gtkshortcutssection.c:407
#: gtk/gtkshortcutssection.c:414
msgid "_Show All"
msgstr "_ყველას ჩვენება"
@@ -3583,27 +3583,27 @@ msgid "Swipe right"
msgstr "გაუსვით მარჯვნივ"
#. Translators: This is placeholder text for the search entry in the shortcuts window
#: gtk/gtkshortcutswindow.c:855 gtk/gtkshortcutswindow.c:922
#: gtk/gtkshortcutswindow.c:927
#: gtk/gtkshortcutswindow.c:879 gtk/gtkshortcutswindow.c:946
#: gtk/gtkshortcutswindow.c:951
msgid "Search Shortcuts"
msgstr "ძებნის მალსახმობები"
#. Translators: This is the window title for the shortcuts window in normal mode
#: gtk/gtkshortcutswindow.c:887 gtk/inspector/window.ui:498
#: gtk/gtkshortcutswindow.c:911 gtk/inspector/window.ui:498
msgid "Shortcuts"
msgstr "მალსახმობები"
#. Translators: This is the window title for the shortcuts window in search mode
#: gtk/gtkshortcutswindow.c:892
#: gtk/gtkshortcutswindow.c:916
msgid "Search Results"
msgstr "ძებნს შედეგები"
#: gtk/gtkshortcutswindow.c:989 gtk/ui/gtkemojichooser.ui:349
#: gtk/gtkshortcutswindow.c:1013 gtk/ui/gtkemojichooser.ui:349
#: gtk/ui/gtkfilechooserwidget.ui:239
msgid "No Results Found"
msgstr "შედეგების გარეშე"
#: gtk/gtkshortcutswindow.c:1000 gtk/ui/gtkemojichooser.ui:362
#: gtk/gtkshortcutswindow.c:1024 gtk/ui/gtkemojichooser.ui:362
#: gtk/ui/gtkfilechooserwidget.ui:252 gtk/ui/gtkplacesview.ui:218
msgid "Try a different search"
msgstr "სცადეთ სხვა ძებნა"
@@ -3678,7 +3678,7 @@ msgid "Description"
msgstr "აღწერა"
#: gtk/inspector/a11y.ui:99 gtk/inspector/misc-info.ui:296
#: tools/gtk-path-tool-info.c:128
#: tools/gtk-path-tool-info.c:132
msgid "Bounds"
msgstr "საზღვრები"
@@ -7453,6 +7453,8 @@ msgid ""
"\n"
"Commands:\n"
" decompose Decompose the path\n"
" reverse Reverse the path\n"
" restrict Restrict the path to a segment\n"
" show Display the path in a window\n"
" render Render the path as an image\n"
" info Print information about the path\n"
@@ -7465,78 +7467,95 @@ msgstr ""
"\n"
"ბრძანებები:\n"
" decompose ბილიკის დაშლა\n"
" reverse ბილიკის შებრუნება\n"
" restrict სეგმენტამდე ბილიკის შეზღუდვა\n"
" show ბილიკის ფანჯარაში ჩვენება\n"
" render ბილიკის რენდერი გამოსახულების სახით\n"
" info ბილიკის შესახებ ინფორმაციის გამოტანა\n"
"\n"
#: tools/gtk-path-tool-decompose.c:75
#: tools/gtk-path-tool-decompose.c:84
msgid "Allow quadratic Bézier curves"
msgstr "კვადრატული ბეზიეს მრუდების დაშვება"
#: tools/gtk-path-tool-decompose.c:76
#: tools/gtk-path-tool-decompose.c:85
msgid "Allow cubic Bézier curves"
msgstr "კუბური ბეზიეს მრუდების დაშვება"
#: tools/gtk-path-tool-decompose.c:77 tools/gtk-path-tool-info.c:88
#: tools/gtk-path-tool-render.c:58 tools/gtk-path-tool-show.c:127
#: tools/gtk-path-tool-decompose.c:86
msgid "Allow conic Bézier curves"
msgstr "კონუსური ბეზიეს მრუდების დაშვება"
#: tools/gtk-path-tool-decompose.c:87 tools/gtk-path-tool-info.c:88
#: tools/gtk-path-tool-render.c:58 tools/gtk-path-tool-restrict.c:38
#: tools/gtk-path-tool-show.c:141
msgid "PATH"
msgstr "ბილიკი"
#: tools/gtk-path-tool-decompose.c:89
#: tools/gtk-path-tool-decompose.c:99
msgid "Decompose a path."
msgstr "ბილიკის დაშლა."
#: tools/gtk-path-tool-decompose.c:102 tools/gtk-path-tool-info.c:112
#: tools/gtk-path-tool-decompose.c:112 tools/gtk-path-tool-info.c:113
#: tools/gtk-path-tool-restrict.c:64
msgid "No paths given."
msgstr "ბილიკები მითითებული არაა."
#: tools/gtk-path-tool-decompose.c:128
#: tools/gtk-path-tool-decompose.c:140 tools/gtk-path-tool-restrict.c:94
msgid "That didn't work out."
msgstr "ამან არ იმუშავა."
#: tools/gtk-path-tool-info.c:99
#: tools/gtk-path-tool-info.c:100
msgid "Print information about a path."
msgstr "ბილიკის შესახებ ინფორმაციის ჩვენება."
#: tools/gtk-path-tool-info.c:119
#: tools/gtk-path-tool-info.c:121
msgid "Path is empty."
msgstr "ბილიკი ცარიელია."
#: tools/gtk-path-tool-info.c:125
#: tools/gtk-path-tool-info.c:127
msgid "Path is closed"
msgstr "ბილიკი დახურულია"
#: tools/gtk-path-tool-info.c:134
#: tools/gtk-path-tool-info.c:129
msgid "Path length"
msgstr "ბილიკის სიგრძე"
#: tools/gtk-path-tool-info.c:138
#, c-format
msgid "%d contours"
msgstr "%d მოხაზულობა"
#: tools/gtk-path-tool-info.c:136
#: tools/gtk-path-tool-info.c:140
#, c-format
msgid "%d operations"
msgstr "%d ოპერაცია"
#: tools/gtk-path-tool-info.c:140
#: tools/gtk-path-tool-info.c:144
#, c-format
msgid "%d lines"
msgstr "%d ხაზი"
#: tools/gtk-path-tool-info.c:145
#: tools/gtk-path-tool-info.c:149
#, c-format
msgid "%d quadratics"
msgstr "%d კვადრატი"
#: tools/gtk-path-tool-info.c:150
#: tools/gtk-path-tool-info.c:154
#, c-format
msgid "%d cubics"
msgstr "%d კუბი"
#: tools/gtk-path-tool-render.c:53 tools/gtk-path-tool-show.c:123
#: tools/gtk-path-tool-info.c:159
#, c-format
msgid "%d conics"
msgstr "%d კონუსი"
#: tools/gtk-path-tool-render.c:53 tools/gtk-path-tool-show.c:135
msgid "Fill the path (the default)"
msgstr "კონტურის შევსება (ნაგულისხმევი)"
#: tools/gtk-path-tool-render.c:54 tools/gtk-path-tool-show.c:124
#: tools/gtk-path-tool-render.c:54 tools/gtk-path-tool-show.c:136
msgid "Stroke the path"
msgstr "კონტურის სვლა"
@@ -7544,58 +7563,58 @@ msgstr "კონტურის სვლა"
msgid "The output file"
msgstr "გამოტანის ფაილი"
#: tools/gtk-path-tool-render.c:56 tools/gtk-path-tool-show.c:125
#: tools/gtk-path-tool-render.c:56 tools/gtk-path-tool-show.c:139
msgid "Foreground color"
msgstr "წინა პლანის ფერი"
#: tools/gtk-path-tool-render.c:56 tools/gtk-path-tool-render.c:57
#: tools/gtk-path-tool-show.c:125 tools/gtk-path-tool-show.c:126
#: tools/gtk-path-tool-show.c:139 tools/gtk-path-tool-show.c:140
msgid "COLOR"
msgstr "ფერი"
#: tools/gtk-path-tool-render.c:57 tools/gtk-path-tool-show.c:126
#: tools/gtk-path-tool-render.c:57 tools/gtk-path-tool-show.c:140
msgid "Background color"
msgstr "ფონის ფერი"
#: tools/gtk-path-tool-render.c:62 tools/gtk-path-tool-show.c:131
#: tools/gtk-path-tool-render.c:62 tools/gtk-path-tool-show.c:145
msgid "Fill rule (winding, even-odd)"
msgstr "შევსების წესი (winding, even-odd)"
#: tools/gtk-path-tool-render.c:62 tools/gtk-path-tool-render.c:66
#: tools/gtk-path-tool-render.c:67 tools/gtk-path-tool-render.c:68
#: tools/gtk-path-tool-render.c:69 tools/gtk-path-tool-render.c:70
#: tools/gtk-path-tool-render.c:71 tools/gtk-path-tool-show.c:131
#: tools/gtk-path-tool-show.c:135 tools/gtk-path-tool-show.c:136
#: tools/gtk-path-tool-show.c:137 tools/gtk-path-tool-show.c:138
#: tools/gtk-path-tool-show.c:139 tools/gtk-path-tool-show.c:140
#: tools/gtk-path-tool-render.c:71 tools/gtk-path-tool-show.c:145
#: tools/gtk-path-tool-show.c:149 tools/gtk-path-tool-show.c:150
#: tools/gtk-path-tool-show.c:151 tools/gtk-path-tool-show.c:152
#: tools/gtk-path-tool-show.c:153 tools/gtk-path-tool-show.c:154
msgid "VALUE"
msgstr "მნიშვნელობა"
#: tools/gtk-path-tool-render.c:66 tools/gtk-path-tool-show.c:135
#: tools/gtk-path-tool-render.c:66 tools/gtk-path-tool-show.c:149
msgid "Line width (number)"
msgstr "ხაზის სიგანე (რიცხვი)"
#: tools/gtk-path-tool-render.c:67 tools/gtk-path-tool-show.c:136
#: tools/gtk-path-tool-render.c:67 tools/gtk-path-tool-show.c:150
msgid "Line cap (butt, round, square)"
msgstr "ხაზის თავი (ისარი, მრგვალი, კვადრატი)"
#: tools/gtk-path-tool-render.c:68 tools/gtk-path-tool-show.c:137
#: tools/gtk-path-tool-render.c:68 tools/gtk-path-tool-show.c:151
msgid "Line join (miter, miter-clip, round, bevel, arcs)"
msgstr "ხაზების შეერთება (miter, miter-clip, round, bevel, arcs)"
#: tools/gtk-path-tool-render.c:69 tools/gtk-path-tool-show.c:138
#: tools/gtk-path-tool-render.c:69 tools/gtk-path-tool-show.c:152
msgid "Miter limit (number)"
msgstr "Miter-ის ლიმიტი (რიცხვი)"
#: tools/gtk-path-tool-render.c:70 tools/gtk-path-tool-show.c:139
#: tools/gtk-path-tool-render.c:70 tools/gtk-path-tool-show.c:153
msgid "Dash pattern (comma-separated numbers)"
msgstr "პუნქტირის ნიმუში (მძიმით გამოყოფილი რიცხვები)"
#: tools/gtk-path-tool-render.c:71 tools/gtk-path-tool-show.c:140
#: tools/gtk-path-tool-render.c:71 tools/gtk-path-tool-show.c:154
msgid "Dash offset (number)"
msgstr "პუნქტირის წანაცვლება (რიცხვი)"
#: tools/gtk-path-tool-render.c:90 tools/gtk-path-tool-show.c:153
#: tools/gtk-path-tool-render.c:90 tools/gtk-path-tool-show.c:167
msgid "Could not initialize windowing system"
msgstr "ფანჯრული სისტემის ინიციალიზაციის შეცდომა"
@@ -7603,23 +7622,23 @@ msgstr "ფანჯრული სისტემის ინიციალ
msgid "Render the path to a png image."
msgstr "ბილიკის რენდერი png გამოსახულებაში."
#: tools/gtk-path-tool-render.c:102 tools/gtk-path-tool-show.c:164
#: tools/gtk-path-tool-render.c:102 tools/gtk-path-tool-show.c:178
msgid "Options related to filling"
msgstr "შევსების პარამეტრები"
#: tools/gtk-path-tool-render.c:103 tools/gtk-path-tool-show.c:165
#: tools/gtk-path-tool-render.c:103 tools/gtk-path-tool-show.c:179
msgid "Show help for fill options"
msgstr "დახმარების ჩვენება შევსების პარამეტრებისთვის"
#: tools/gtk-path-tool-render.c:110 tools/gtk-path-tool-show.c:172
#: tools/gtk-path-tool-render.c:110 tools/gtk-path-tool-show.c:186
msgid "Options related to stroking"
msgstr "სვლის პარამეტრები"
#: tools/gtk-path-tool-render.c:111 tools/gtk-path-tool-show.c:173
#: tools/gtk-path-tool-render.c:111 tools/gtk-path-tool-show.c:187
msgid "Show help for stroke options"
msgstr "დახმარების ჩვენება სვლის პარამეტრებისთვის"
#: tools/gtk-path-tool-render.c:128 tools/gtk-path-tool-show.c:190
#: tools/gtk-path-tool-render.c:128 tools/gtk-path-tool-show.c:204
msgid "No path specified"
msgstr "ბილიკი მითითებული არაა"
@@ -7627,42 +7646,61 @@ msgstr "ბილიკი მითითებული არაა"
msgid "Can only render a single path"
msgstr "შესაძლებელია მხოლოდ ერთ ბილიკის რენდერი"
#: tools/gtk-path-tool-render.c:140 tools/gtk-path-tool-show.c:202
#: tools/gtk-path-tool-render.c:140 tools/gtk-path-tool-show.c:216
msgid "fill rule"
msgstr "შევსების წესი"
#: tools/gtk-path-tool-render.c:144 tools/gtk-path-tool-show.c:206
#: tools/gtk-path-tool-render.c:144 tools/gtk-path-tool-show.c:220
msgid "line cap"
msgstr "ხაზის თავი"
#: tools/gtk-path-tool-render.c:145 tools/gtk-path-tool-show.c:207
#: tools/gtk-path-tool-render.c:145 tools/gtk-path-tool-show.c:221
msgid "line join"
msgstr "ხაზების შეერთება"
#: tools/gtk-path-tool-render.c:169 tools/gtk-path-tool-show.c:231
#, c-format
msgid "Failed to parse '%s' as number"
msgstr "'%s'-ის რიცხვის სახით წაკითხვა შეუძლებელია"
#: tools/gtk-path-tool-render.c:213
#: tools/gtk-path-tool-render.c:181
#, c-format
msgid "Saving png to '%s' failed"
msgstr "PNG-ის '%s'-ში შენახვა შეუძლებელია"
#: tools/gtk-path-tool-render.c:220
#: tools/gtk-path-tool-render.c:188
#, c-format
msgid "Output written to '%s'."
msgstr "გამოტანილი ინფორმაცია ჩაწერილია %s-ში."
#: tools/gtk-path-tool-show.c:43 tools/gtk-path-tool-show.c:78
#: tools/gtk-path-tool-restrict.c:36
msgid "Beginning of segment"
msgstr "სეგმენტის დასაწყისი"
#: tools/gtk-path-tool-restrict.c:36 tools/gtk-path-tool-restrict.c:37
msgid "LENGTH"
msgstr "სიგრძე"
#: tools/gtk-path-tool-restrict.c:37
msgid "End of segment"
msgstr "სეგმენტის დასასრული"
#: tools/gtk-path-tool-restrict.c:51
msgid "Restrict a path to a segment."
msgstr "სეგმენტამდე ბილიკის შეზღუდვა"
#: tools/gtk-path-tool-show.c:45 tools/gtk-path-tool-show.c:85
msgid "Path Preview"
msgstr "ბილიკის მინიატურა"
#: tools/gtk-path-tool-show.c:161
#: tools/gtk-path-tool-show.c:137
msgid "Show points"
msgstr "წერტილების ჩვენება"
#: tools/gtk-path-tool-show.c:138
msgid "Show controls"
msgstr "კონტროლების ჩვენება"
#: tools/gtk-path-tool-show.c:175
msgid "Display the path."
msgstr "ბილიკის ჩვენება."
#: tools/gtk-path-tool-show.c:196
#: tools/gtk-path-tool-show.c:210
msgid "Can only show a single path"
msgstr "შესაძლებელია მხოლოდ ერთი ბილიკის ჩვენება"
@@ -7695,6 +7733,11 @@ msgstr "შესაძლო მნიშვნელობები: "
msgid "Could not parse '%s' as color"
msgstr "'%s'-ის ფერის სახით დამუშავება შეუძლებელია"
#: tools/gtk-path-tool-utils.c:163
#, c-format
msgid "Failed to parse '%s' as number"
msgstr "'%s'-ის რიცხვის სახით წაკითხვა შეუძლებელია"
#: tools/gtk-rendernode-tool.c:35
#, c-format
msgid ""
+1174 -865
View File
File diff suppressed because it is too large Load Diff
+1187 -895
View File
File diff suppressed because it is too large Load Diff
+2331 -2125
View File
File diff suppressed because it is too large Load Diff
+958 -763
View File
File diff suppressed because it is too large Load Diff
+4117 -3347
View File
File diff suppressed because it is too large Load Diff
+229 -171
View File
@@ -16,8 +16,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gtk\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gtk/-/issues/\n"
"POT-Creation-Date: 2023-08-22 16:19+0000\n"
"PO-Revision-Date: 2023-08-23 16:42+0200\n"
"POT-Creation-Date: 2023-09-16 14:27+0000\n"
"PO-Revision-Date: 2023-09-17 12:15+0200\n"
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
"Language-Team: Polish <community-poland@mozilla.org>\n"
"Language: pl\n"
@@ -59,31 +59,31 @@ msgstr "Nie można dostarczyć zawartości jako %s"
msgid "The current backend does not support OpenGL"
msgstr "Bieżący mechanizm nie obsługuje OpenGL"
#: gdk/gdkdisplay.c:1245 gdk/gdksurface.c:1252
#: gdk/gdkdisplay.c:1244 gdk/gdksurface.c:1252
msgid "Vulkan support disabled via GDK_DEBUG"
msgstr "Obsługa Vulkan została wyłączona przez zmienną GDK_DEBUG"
#: gdk/gdkdisplay.c:1277
#: gdk/gdkdisplay.c:1276
msgid "GL support disabled via GDK_DEBUG"
msgstr "Obsługa GL została wyłączona przez zmienną GDK_DEBUG"
#: gdk/gdkdisplay.c:1575
#: gdk/gdkdisplay.c:1574
msgid "No EGL configuration available"
msgstr "Brak dostępnej konfiguracji EGL"
#: gdk/gdkdisplay.c:1583
#: gdk/gdkdisplay.c:1582
msgid "Failed to get EGL configurations"
msgstr "Uzyskanie konfiguracji EGL się nie powiodło"
#: gdk/gdkdisplay.c:1613
#: gdk/gdkdisplay.c:1612
msgid "No EGL configuration with required features found"
msgstr "Nie odnaleziono konfiguracji EGL z wymaganymi funkcjami"
#: gdk/gdkdisplay.c:1620
#: gdk/gdkdisplay.c:1619
msgid "No perfect EGL configuration found"
msgstr "Nie odnaleziono doskonałej konfiguracji EGL"
#: gdk/gdkdisplay.c:1662
#: gdk/gdkdisplay.c:1661
#, c-format
msgid "EGL implementation is missing extension %s"
msgid_plural "EGL implementation is missing %2$d extensions: %1$s"
@@ -91,23 +91,23 @@ msgstr[0] "W implementacji EGL brakuje rozszerzenia %s"
msgstr[1] "W implementacji EGL brakuje %2$d rozszerzeń: %1$s"
msgstr[2] "W implementacji EGL brakuje %2$d rozszerzeń: %1$s"
#: gdk/gdkdisplay.c:1695
#: gdk/gdkdisplay.c:1694
msgid "libEGL not available in this sandbox"
msgstr "libEGL nie jest dostępne w tej izolacji"
#: gdk/gdkdisplay.c:1696
#: gdk/gdkdisplay.c:1695
msgid "libEGL not available"
msgstr "libEGL jest niedostępne"
#: gdk/gdkdisplay.c:1706
#: gdk/gdkdisplay.c:1705
msgid "Failed to create EGL display"
msgstr "Utworzenie ekranu EGL się nie powiodło"
#: gdk/gdkdisplay.c:1716
#: gdk/gdkdisplay.c:1715
msgid "Could not initialize EGL display"
msgstr "Nie można zainicjować ekranu EGL"
#: gdk/gdkdisplay.c:1727
#: gdk/gdkdisplay.c:1726
#, c-format
msgid "EGL version %d.%d is too old. GTK requires %d.%d"
msgstr "Wersja EGL, %d.%d, jest za stara. GTK wymaga wersji %d.%d"
@@ -1093,7 +1093,7 @@ msgstr "Sans 12"
msgid "Pick a Font"
msgstr "Wybór czcionki"
#: gtk/deprecated/gtkfontbutton.c:597 gtk/gtkfilechooserwidget.c:3871
#: gtk/deprecated/gtkfontbutton.c:597 gtk/gtkfilechooserwidget.c:3806
#: gtk/gtkfontdialogbutton.c:126 gtk/inspector/visual.ui:169
msgid "Font"
msgstr "Czcionka"
@@ -2163,7 +2163,7 @@ msgstr "_Prawy:"
msgid "Paper Margins"
msgstr "Marginesy papieru"
#: gtk/gtkentry.c:3673
#: gtk/gtkentry.c:3685
msgid "Insert Emoji"
msgstr "Wstawia emoji"
@@ -2228,7 +2228,7 @@ msgid "A file with that name already exists"
msgstr "Plik o tej nazwie już istnieje"
#: gtk/gtkfilechoosernative.c:520 gtk/gtkfilechoosernative.c:600
#: gtk/gtkfilechooserwidget.c:1185 gtk/gtkfilechooserwidget.c:5029
#: gtk/gtkfilechooserwidget.c:1183 gtk/gtkfilechooserwidget.c:4964
#: gtk/gtkfiledialog.c:843 gtk/gtkmessagedialog.c:170
#: gtk/gtkmessagedialog.c:179 gtk/gtkmountoperation.c:608
#: gtk/print/gtkpagesetupunixdialog.c:282 gtk/print/gtkprintbackend.c:638
@@ -2262,253 +2262,241 @@ msgstr "Wybór typów wyświetlanych plików"
msgid "%1$s on %2$s"
msgstr "%1$s na %2$s"
#: gtk/gtkfilechooserwidget.c:345
#: gtk/gtkfilechooserwidget.c:343
msgid "Type name of new folder"
msgstr "Nazwa nowego katalogu"
#: gtk/gtkfilechooserwidget.c:727
#: gtk/gtkfilechooserwidget.c:725
msgid "The folder could not be created"
msgstr "Nie można utworzyć katalogu"
#: gtk/gtkfilechooserwidget.c:740
#: gtk/gtkfilechooserwidget.c:738
msgid "You need to choose a valid filename."
msgstr "Należy wybrać prawidłową nazwę pliku."
#: gtk/gtkfilechooserwidget.c:743
#: gtk/gtkfilechooserwidget.c:741
#, c-format
msgid "Cannot create a file under %s as it is not a folder"
msgstr "Nie można utworzyć pliku w %s, ponieważ nie jest katalogiem"
#: gtk/gtkfilechooserwidget.c:753
#: gtk/gtkfilechooserwidget.c:751
msgid "Cannot create file as the filename is too long"
msgstr "Nie można utworzyć pliku, ponieważ jego nazwa jest za długa"
#: gtk/gtkfilechooserwidget.c:754
#: gtk/gtkfilechooserwidget.c:752
msgid "Try using a shorter name."
msgstr "Proszę spróbować krótszej nazwy."
#: gtk/gtkfilechooserwidget.c:764
#: gtk/gtkfilechooserwidget.c:762
msgid "You may only select folders"
msgstr "Można wybierać tylko katalogi"
#: gtk/gtkfilechooserwidget.c:765
#: gtk/gtkfilechooserwidget.c:763
msgid "The item that you selected is not a folder try using a different item."
msgstr ""
"Wybrany element nie jest katalogiem, proszę spróbować użyć innego elementu."
#: gtk/gtkfilechooserwidget.c:773
#: gtk/gtkfilechooserwidget.c:771
msgid "Invalid file name"
msgstr "Nieprawidłowa nazwa pliku"
#: gtk/gtkfilechooserwidget.c:782
#: gtk/gtkfilechooserwidget.c:780
msgid "The folder contents could not be displayed"
msgstr "Nie można wyświetlić zawartości katalogu"
#: gtk/gtkfilechooserwidget.c:790
#: gtk/gtkfilechooserwidget.c:788
msgid "The file could not be deleted"
msgstr "Nie można usunąć pliku"
#: gtk/gtkfilechooserwidget.c:798
#: gtk/gtkfilechooserwidget.c:796
msgid "The file could not be moved to the Trash"
msgstr "Nie można przenieść pliku do kosza"
#: gtk/gtkfilechooserwidget.c:1183
#: gtk/gtkfilechooserwidget.c:1181
#, c-format
msgid "Are you sure you want to permanently delete “%s”?"
msgstr "Na pewno trwale usunąć „%s”?"
#: gtk/gtkfilechooserwidget.c:1184
#: gtk/gtkfilechooserwidget.c:1182
msgid "If you delete an item, it will be permanently lost."
msgstr "Jeśli element zostanie usunięty, to zostanie on bezpowrotnie utracony."
#: gtk/gtkfilechooserwidget.c:1185 gtk/gtkfilechooserwidget.c:1815
#: gtk/gtkfilechooserwidget.c:1183 gtk/gtkfilechooserwidget.c:1781
#: gtk/gtklabel.c:5695 gtk/gtktext.c:6145 gtk/gtktextview.c:9018
msgid "_Delete"
msgstr "_Usuń"
#: gtk/gtkfilechooserwidget.c:1298
#: gtk/gtkfilechooserwidget.c:1296
msgid "The file could not be renamed"
msgstr "Nie można zmienić nazwy pliku"
#: gtk/gtkfilechooserwidget.c:1504
#: gtk/gtkfilechooserwidget.c:1472
msgid "Could not select file"
msgstr "Nie można wybrać pliku"
#: gtk/gtkfilechooserwidget.c:1724 gtk/ui/gtkfilechooserwidget.ui:66
#: gtk/gtkfilechooserwidget.c:1692 gtk/ui/gtkfilechooserwidget.ui:66
msgid "Grid View"
msgstr "Widok siatki"
#: gtk/gtkfilechooserwidget.c:1730
#: gtk/gtkfilechooserwidget.c:1698
msgid "List View"
msgstr "Widok listy"
#: gtk/gtkfilechooserwidget.c:1795
#: gtk/gtkfilechooserwidget.c:1761
msgid "_Visit File"
msgstr "Od_wiedź plik"
#: gtk/gtkfilechooserwidget.c:1799
#: gtk/gtkfilechooserwidget.c:1765
msgid "_Open With File Manager"
msgstr "_Otwórz w menedżerze plików"
#: gtk/gtkfilechooserwidget.c:1803
#: gtk/gtkfilechooserwidget.c:1769
msgid "_Copy Location"
msgstr "S_kopiuj położenie"
#: gtk/gtkfilechooserwidget.c:1807
#: gtk/gtkfilechooserwidget.c:1773
msgid "_Add to Bookmarks"
msgstr "_Dodaj zakładkę"
#: gtk/gtkfilechooserwidget.c:1811 gtk/gtkplacessidebar.c:2312
#: gtk/gtkfilechooserwidget.c:1777 gtk/gtkplacessidebar.c:2312
#: gtk/gtkplacessidebar.c:3270 gtk/ui/gtkfilechooserwidget.ui:410
msgid "_Rename"
msgstr "Z_mień nazwę"
#: gtk/gtkfilechooserwidget.c:1819
#: gtk/gtkfilechooserwidget.c:1785
msgid "_Move to Trash"
msgstr "_Przenieś do kosza"
#: gtk/gtkfilechooserwidget.c:1828
#: gtk/gtkfilechooserwidget.c:1794
msgid "Show _Hidden Files"
msgstr "_Ukryte pliki"
#: gtk/gtkfilechooserwidget.c:1832
msgid "Show _Size Column"
msgstr "_Rozmiar"
#: gtk/gtkfilechooserwidget.c:1837
msgid "Show T_ype Column"
msgstr "_Typ"
#: gtk/gtkfilechooserwidget.c:1842
msgid "Show _Time"
msgstr "_Czas"
#: gtk/gtkfilechooserwidget.c:1847
#: gtk/gtkfilechooserwidget.c:1798
msgid "Sort _Folders Before Files"
msgstr "K_atalogi przed plikami"
#: gtk/gtkfilechooserwidget.c:1979 gtk/gtkfilechooserwidget.c:2009
#: gtk/gtkfilechooserwidget.c:3914
#: gtk/gtkfilechooserwidget.c:1921 gtk/gtkfilechooserwidget.c:1951
#: gtk/gtkfilechooserwidget.c:3849
msgid "Unknown"
msgstr "Nieznane"
#: gtk/gtkfilechooserwidget.c:2064 gtk/gtkplacessidebar.c:1025
#: gtk/gtkfilechooserwidget.c:2006 gtk/gtkplacessidebar.c:1025
msgid "Home"
msgstr "Katalog domowy"
#. this is the header for the location column in the print dialog
#: gtk/gtkfilechooserwidget.c:2219 gtk/gtkfilechooserwidget.c:7415
#: gtk/gtkfilechooserwidget.c:2161 gtk/gtkfilechooserwidget.c:7374
#: gtk/inspector/css-node-tree.ui:76 gtk/print/ui/gtkprintunixdialog.ui:111
msgid "Location"
msgstr "Położenie"
#. Label
#: gtk/gtkfilechooserwidget.c:2326
#: gtk/gtkfilechooserwidget.c:2268
msgid "_Name:"
msgstr "_Nazwa:"
#: gtk/gtkfilechooserwidget.c:2881 gtk/gtkfilechooserwidget.c:2895
#: gtk/gtkfilechooserwidget.c:2823 gtk/gtkfilechooserwidget.c:2837
#, c-format
msgid "Searching in %s"
msgstr "Wyszukiwanie w „%s”"
#: gtk/gtkfilechooserwidget.c:2901
#: gtk/gtkfilechooserwidget.c:2843
msgid "Searching"
msgstr "Wyszukiwanie"
#: gtk/gtkfilechooserwidget.c:2907
#: gtk/gtkfilechooserwidget.c:2849
msgid "Enter location or URL"
msgstr "Proszę wprowadzić położenie lub adres URL"
#: gtk/gtkfilechooserwidget.c:3474 gtk/gtkfilechooserwidget.c:5814
#: gtk/gtkfilechooserwidget.c:7434
#: gtk/gtkfilechooserwidget.c:3408 gtk/gtkfilechooserwidget.c:5749
#: gtk/gtkfilechooserwidget.c:7396
msgid "Modified"
msgstr "Modyfikacja"
#: gtk/gtkfilechooserwidget.c:3658
#: gtk/gtkfilechooserwidget.c:3593
#, c-format
msgid "Could not read the contents of %s"
msgstr "Nie można odczytać zawartości „%s”"
#: gtk/gtkfilechooserwidget.c:3662
#: gtk/gtkfilechooserwidget.c:3597
msgid "Could not read the contents of the folder"
msgstr "Nie można odczytać zawartości katalogu"
#. Translators: see g_date_time_format() for details on the format
#: gtk/gtkfilechooserwidget.c:3809 gtk/gtkfilechooserwidget.c:3852
#: gtk/gtkfilechooserwidget.c:3744 gtk/gtkfilechooserwidget.c:3787
msgid "%H:%M"
msgstr "%H%M"
#: gtk/gtkfilechooserwidget.c:3811 gtk/gtkfilechooserwidget.c:3854
#: gtk/gtkfilechooserwidget.c:3746 gtk/gtkfilechooserwidget.c:3789
msgid "%l:%M %p"
msgstr "%-l%M%p"
#: gtk/gtkfilechooserwidget.c:3815
#: gtk/gtkfilechooserwidget.c:3750
msgid "Yesterday"
msgstr "Wczoraj"
#: gtk/gtkfilechooserwidget.c:3823
#: gtk/gtkfilechooserwidget.c:3758
msgid "%-e %b"
msgstr "%-d %b"
#: gtk/gtkfilechooserwidget.c:3827
#: gtk/gtkfilechooserwidget.c:3762
msgid "%-e %b %Y"
msgstr "%-d %b %Y"
#: gtk/gtkfilechooserwidget.c:3869 gtk/gtkfilechooserwidget.c:3877
#: gtk/gtkfilechooserwidget.c:3804 gtk/gtkfilechooserwidget.c:3812
msgid "Program"
msgstr "Program"
#: gtk/gtkfilechooserwidget.c:3870
#: gtk/gtkfilechooserwidget.c:3805
msgid "Audio"
msgstr "Dźwięk"
#: gtk/gtkfilechooserwidget.c:3872 gtk/gtkfilefilter.c:1032
#: gtk/gtkfilechooserwidget.c:3807 gtk/gtkfilefilter.c:1032
msgid "Image"
msgstr "Obraz"
#: gtk/gtkfilechooserwidget.c:3873
#: gtk/gtkfilechooserwidget.c:3808
msgid "Archive"
msgstr "Archiwum"
#: gtk/gtkfilechooserwidget.c:3874
#: gtk/gtkfilechooserwidget.c:3809
msgid "Markup"
msgstr "Hipertekst"
#: gtk/gtkfilechooserwidget.c:3875 gtk/gtkfilechooserwidget.c:3876
#: gtk/gtkfilechooserwidget.c:3810 gtk/gtkfilechooserwidget.c:3811
msgid "Text"
msgstr "Tekst"
#: gtk/gtkfilechooserwidget.c:3878
#: gtk/gtkfilechooserwidget.c:3813
msgid "Video"
msgstr "Wideo"
#: gtk/gtkfilechooserwidget.c:3879
#: gtk/gtkfilechooserwidget.c:3814
msgid "Contacts"
msgstr "Kontakty"
#: gtk/gtkfilechooserwidget.c:3880
#: gtk/gtkfilechooserwidget.c:3815
msgid "Calendar"
msgstr "Kalendarz"
#: gtk/gtkfilechooserwidget.c:3881
#: gtk/gtkfilechooserwidget.c:3816
msgid "Document"
msgstr "Dokument"
#: gtk/gtkfilechooserwidget.c:3882
#: gtk/gtkfilechooserwidget.c:3817
msgid "Presentation"
msgstr "Prezentacja"
#: gtk/gtkfilechooserwidget.c:3883
#: gtk/gtkfilechooserwidget.c:3818
msgid "Spreadsheet"
msgstr "Arkusz kalkulacyjny"
#: gtk/gtkfilechooserwidget.c:5021 gtk/print/gtkprintunixdialog.c:673
#: gtk/gtkfilechooserwidget.c:4956 gtk/print/gtkprintunixdialog.c:673
#, c-format
msgid "A file named “%s” already exists. Do you want to replace it?"
msgstr "Plik o nazwie „%s” już istnieje. Zastąpić go?"
#: gtk/gtkfilechooserwidget.c:5023 gtk/print/gtkprintunixdialog.c:677
#: gtk/gtkfilechooserwidget.c:4958 gtk/print/gtkprintunixdialog.c:677
#, c-format
msgid ""
"The file already exists in “%s”. Replacing it will overwrite its contents."
@@ -2516,35 +2504,47 @@ msgstr ""
"Plik już istnieje w „%s”. Zastąpienie go spowoduje nadpisanie jego "
"zawartości."
#: gtk/gtkfilechooserwidget.c:5029 gtk/print/gtkprintunixdialog.c:685
#: gtk/gtkfilechooserwidget.c:4964 gtk/print/gtkprintunixdialog.c:685
msgid "_Replace"
msgstr "_Zastąp"
#: gtk/gtkfilechooserwidget.c:5184
#: gtk/gtkfilechooserwidget.c:5119
msgid "You do not have access to the specified folder."
msgstr "Brak dostępu do podanego katalogu."
#: gtk/gtkfilechooserwidget.c:5761
#: gtk/gtkfilechooserwidget.c:5696
msgid "Could not send the search request"
msgstr "Nie można wysłać żądania wyszukiwania"
#: gtk/gtkfilechooserwidget.c:6042
#: gtk/gtkfilechooserwidget.c:5977
msgid "Accessed"
msgstr "Dostęp"
#: gtk/gtkfilechooserwidget.c:7408 gtk/gtkplacessidebar.c:2306
#: gtk/gtkfilechooserwidget.c:7352
msgid "_Size"
msgstr "_Rozmiar"
#: gtk/gtkfilechooserwidget.c:7356
msgid "T_ype"
msgstr "_Typ"
#: gtk/gtkfilechooserwidget.c:7360
msgid "_Time"
msgstr "_Czas"
#: gtk/gtkfilechooserwidget.c:7366 gtk/gtkplacessidebar.c:2306
#: gtk/inspector/a11y.ui:43 gtk/inspector/actions.ui:19
#: gtk/inspector/css-node-tree.ui:22 gtk/inspector/prop-list.ui:24
#: gtk/ui/gtkfilechooserwidget.ui:385 gtk/print/ui/gtkprintunixdialog.ui:80
msgid "Name"
msgstr "Nazwa"
#: gtk/gtkfilechooserwidget.c:7423 gtk/inspector/resource-list.ui:82
#: gtk/gtkfilechooserwidget.c:7383 gtk/inspector/resource-list.ui:82
#: gtk/ui/gtkfontchooserwidget.ui:217 gtk/ui/gtkfontchooserwidget.ui:386
msgid "Size"
msgstr "Rozmiar"
#: gtk/gtkfilechooserwidget.c:7428 gtk/inspector/misc-info.ui:57
#: gtk/gtkfilechooserwidget.c:7389 gtk/inspector/misc-info.ui:57
#: gtk/inspector/prop-list.ui:35 gtk/inspector/statistics.ui:36
msgid "Type"
msgstr "Typ"
@@ -2890,7 +2890,7 @@ msgstr "Poprzednia karta"
msgid "Next tab"
msgstr "Następna karta"
#: gtk/gtknotebook.c:4331 gtk/gtknotebook.c:6539
#: gtk/gtknotebook.c:4331 gtk/gtknotebook.c:6541
#, c-format
msgid "Page %u"
msgstr "%u. strona"
@@ -3535,7 +3535,7 @@ msgstr ""
"Nie odnaleziono zarejestrowanego programu o nazwie „%s” dla elementu "
"o adresie URI „%s”"
#: gtk/gtksearchentry.c:758
#: gtk/gtksearchentry.c:767
msgid "Clear Entry"
msgstr "Czyści wpis"
@@ -3559,7 +3559,7 @@ msgctxt "keyboard side marker"
msgid "R"
msgstr "P"
#: gtk/gtkshortcutssection.c:407
#: gtk/gtkshortcutssection.c:414
msgid "_Show All"
msgstr "_Wyświetl wszystkie"
@@ -3596,27 +3596,27 @@ msgid "Swipe right"
msgstr "Przeciągnięcie w prawo"
#. Translators: This is placeholder text for the search entry in the shortcuts window
#: gtk/gtkshortcutswindow.c:855 gtk/gtkshortcutswindow.c:922
#: gtk/gtkshortcutswindow.c:927
#: gtk/gtkshortcutswindow.c:879 gtk/gtkshortcutswindow.c:946
#: gtk/gtkshortcutswindow.c:951
msgid "Search Shortcuts"
msgstr "Wyszukiwanie skrótów"
#. Translators: This is the window title for the shortcuts window in normal mode
#: gtk/gtkshortcutswindow.c:887 gtk/inspector/window.ui:498
#: gtk/gtkshortcutswindow.c:911 gtk/inspector/window.ui:498
msgid "Shortcuts"
msgstr "Skróty"
#. Translators: This is the window title for the shortcuts window in search mode
#: gtk/gtkshortcutswindow.c:892
#: gtk/gtkshortcutswindow.c:916
msgid "Search Results"
msgstr "Wyniki wyszukiwania"
#: gtk/gtkshortcutswindow.c:989 gtk/ui/gtkemojichooser.ui:349
#: gtk/gtkshortcutswindow.c:1013 gtk/ui/gtkemojichooser.ui:349
#: gtk/ui/gtkfilechooserwidget.ui:239
msgid "No Results Found"
msgstr "Brak wyników"
#: gtk/gtkshortcutswindow.c:1000 gtk/ui/gtkemojichooser.ui:362
#: gtk/gtkshortcutswindow.c:1024 gtk/ui/gtkemojichooser.ui:362
#: gtk/ui/gtkfilechooserwidget.ui:252 gtk/ui/gtkplacesview.ui:218
msgid "Try a different search"
msgstr "Proszę spróbować innych słów"
@@ -3691,7 +3691,7 @@ msgid "Description"
msgstr "Opis"
#: gtk/inspector/a11y.ui:99 gtk/inspector/misc-info.ui:296
#: tools/gtk-path-tool-info.c:128
#: tools/gtk-path-tool-info.c:132
msgid "Bounds"
msgstr "Granice"
@@ -7200,7 +7200,7 @@ msgstr ""
#: tools/gtk-builder-tool-enumerate.c:56 tools/gtk-builder-tool-preview.c:179
#: tools/gtk-builder-tool-preview.c:180 tools/gtk-builder-tool-screenshot.c:360
#: tools/gtk-builder-tool-simplify.c:2529 tools/gtk-builder-tool-validate.c:261
#: tools/gtk-path-tool-render.c:55 tools/gtk-rendernode-tool-info.c:208
#: tools/gtk-path-tool-render.c:121 tools/gtk-rendernode-tool-info.c:210
#: tools/gtk-rendernode-tool-show.c:102
msgid "FILE"
msgstr "PLIK"
@@ -7471,6 +7471,8 @@ msgid ""
"\n"
"Commands:\n"
" decompose Decompose the path\n"
" reverse Reverse the path\n"
" restrict Restrict the path to a segment\n"
" show Display the path in a window\n"
" render Render the path as an image\n"
" info Print information about the path\n"
@@ -7483,204 +7485,250 @@ msgstr ""
"\n"
"Polecenia:\n"
" decompose Rozkłada ścieżkę\n"
" reverse Odwraca ścieżkę\n"
" restrict Ogranicza ścieżkę do segmentu\n"
" show Wyświetla ścieżkę w oknie\n"
" render Rysuje ścieżkę jako obraz\n"
" info Wyświetla informacje o ścieżce\n"
"\n"
#: tools/gtk-path-tool-decompose.c:75
#: tools/gtk-path-tool-decompose.c:84
msgid "Allow quadratic Bézier curves"
msgstr "Zezwala na kwadratowe krzywe Béziera"
#: tools/gtk-path-tool-decompose.c:76
#: tools/gtk-path-tool-decompose.c:85
msgid "Allow cubic Bézier curves"
msgstr "Zezwala na sześcienne krzywe Béziera"
#: tools/gtk-path-tool-decompose.c:77 tools/gtk-path-tool-info.c:88
#: tools/gtk-path-tool-render.c:58 tools/gtk-path-tool-show.c:127
#: tools/gtk-path-tool-decompose.c:86
msgid "Allow conic Bézier curves"
msgstr "Zezwala na stożkowe krzywe Béziera"
#: tools/gtk-path-tool-decompose.c:87 tools/gtk-path-tool-info.c:88
#: tools/gtk-path-tool-render.c:125 tools/gtk-path-tool-restrict.c:38
#: tools/gtk-path-tool-reverse.c:34 tools/gtk-path-tool-show.c:147
msgid "PATH"
msgstr "ŚCIEŻKA"
#: tools/gtk-path-tool-decompose.c:89
#: tools/gtk-path-tool-decompose.c:99
msgid "Decompose a path."
msgstr "Rozkłada ścieżkę."
#: tools/gtk-path-tool-decompose.c:102 tools/gtk-path-tool-info.c:112
#: tools/gtk-path-tool-decompose.c:112 tools/gtk-path-tool-info.c:113
#: tools/gtk-path-tool-restrict.c:64 tools/gtk-path-tool-reverse.c:58
msgid "No paths given."
msgstr "Nie podano ścieżek."
#: tools/gtk-path-tool-decompose.c:128
#: tools/gtk-path-tool-decompose.c:140 tools/gtk-path-tool-restrict.c:94
#: tools/gtk-path-tool-reverse.c:78
msgid "That didn't work out."
msgstr "To nie zadziałało."
#: tools/gtk-path-tool-info.c:99
#: tools/gtk-path-tool-info.c:100
msgid "Print information about a path."
msgstr "Wyświetla informacje o ścieżce."
#: tools/gtk-path-tool-info.c:119
#: tools/gtk-path-tool-info.c:121
msgid "Path is empty."
msgstr "Ścieżka jest pusta."
#: tools/gtk-path-tool-info.c:125
#: tools/gtk-path-tool-info.c:127
msgid "Path is closed"
msgstr "Ścieżka jest zamknięta"
#: tools/gtk-path-tool-info.c:134
#: tools/gtk-path-tool-info.c:129
msgid "Path length"
msgstr "Długość ścieżki"
#: tools/gtk-path-tool-info.c:138
#, c-format
msgid "%d contours"
msgstr "Obrysy: %d"
#: tools/gtk-path-tool-info.c:136
#: tools/gtk-path-tool-info.c:140
#, c-format
msgid "%d operations"
msgstr "Działania: %d"
#: tools/gtk-path-tool-info.c:140
#: tools/gtk-path-tool-info.c:144
#, c-format
msgid "%d lines"
msgstr "Linie: %d"
#: tools/gtk-path-tool-info.c:145
#: tools/gtk-path-tool-info.c:149
#, c-format
msgid "%d quadratics"
msgstr "Równania kwadratowe: %d"
msgstr "Krzywe kwadratowe: %d"
#: tools/gtk-path-tool-info.c:150
#: tools/gtk-path-tool-info.c:154
#, c-format
msgid "%d cubics"
msgstr "Równania sześcienne: %d"
msgstr "Krzywe sześcienne: %d"
#: tools/gtk-path-tool-render.c:53 tools/gtk-path-tool-show.c:123
#: tools/gtk-path-tool-info.c:159
#, c-format
msgid "%d conics"
msgstr "Krzywe stożkowe: %d"
#: tools/gtk-path-tool-render.c:117 tools/gtk-path-tool-show.c:140
msgid "Fill the path (the default)"
msgstr "Wypełnia ścieżkę (domyślnie)"
#: tools/gtk-path-tool-render.c:54 tools/gtk-path-tool-show.c:124
#: tools/gtk-path-tool-render.c:118 tools/gtk-path-tool-show.c:141
msgid "Stroke the path"
msgstr "Pociąga ścieżkę"
#: tools/gtk-path-tool-render.c:55
#: tools/gtk-path-tool-render.c:119 tools/gtk-path-tool-show.c:142
msgid "Show path points"
msgstr "Wyświetla punkty ścieżki"
#: tools/gtk-path-tool-render.c:120 tools/gtk-path-tool-show.c:143
msgid "Show control points"
msgstr "Wyświetla punkty kontrolne"
#: tools/gtk-path-tool-render.c:121
msgid "The output file"
msgstr "Plik wyjściowy"
#: tools/gtk-path-tool-render.c:56 tools/gtk-path-tool-show.c:125
#: tools/gtk-path-tool-render.c:122 tools/gtk-path-tool-show.c:144
msgid "Foreground color"
msgstr "Kolor pierwszego planu"
#: tools/gtk-path-tool-render.c:56 tools/gtk-path-tool-render.c:57
#: tools/gtk-path-tool-show.c:125 tools/gtk-path-tool-show.c:126
#: tools/gtk-path-tool-render.c:122 tools/gtk-path-tool-render.c:123
#: tools/gtk-path-tool-render.c:124 tools/gtk-path-tool-show.c:144
#: tools/gtk-path-tool-show.c:145 tools/gtk-path-tool-show.c:146
msgid "COLOR"
msgstr "KOLOR"
#: tools/gtk-path-tool-render.c:57 tools/gtk-path-tool-show.c:126
#: tools/gtk-path-tool-render.c:123 tools/gtk-path-tool-show.c:145
msgid "Background color"
msgstr "Kolor tła"
#: tools/gtk-path-tool-render.c:62 tools/gtk-path-tool-show.c:131
#: tools/gtk-path-tool-render.c:124 tools/gtk-path-tool-show.c:146
msgid "Point color"
msgstr "Kolor punktów"
#: tools/gtk-path-tool-render.c:129 tools/gtk-path-tool-show.c:151
msgid "Fill rule (winding, even-odd)"
msgstr "Reguła wypełniania (kręcona, parzysta-nieparzysta)"
#: tools/gtk-path-tool-render.c:62 tools/gtk-path-tool-render.c:66
#: tools/gtk-path-tool-render.c:67 tools/gtk-path-tool-render.c:68
#: tools/gtk-path-tool-render.c:69 tools/gtk-path-tool-render.c:70
#: tools/gtk-path-tool-render.c:71 tools/gtk-path-tool-show.c:131
#: tools/gtk-path-tool-show.c:135 tools/gtk-path-tool-show.c:136
#: tools/gtk-path-tool-show.c:137 tools/gtk-path-tool-show.c:138
#: tools/gtk-path-tool-show.c:139 tools/gtk-path-tool-show.c:140
#: tools/gtk-path-tool-render.c:129 tools/gtk-path-tool-render.c:133
#: tools/gtk-path-tool-render.c:134 tools/gtk-path-tool-render.c:135
#: tools/gtk-path-tool-render.c:136 tools/gtk-path-tool-render.c:137
#: tools/gtk-path-tool-render.c:138 tools/gtk-path-tool-show.c:151
#: tools/gtk-path-tool-show.c:155 tools/gtk-path-tool-show.c:156
#: tools/gtk-path-tool-show.c:157 tools/gtk-path-tool-show.c:158
#: tools/gtk-path-tool-show.c:159 tools/gtk-path-tool-show.c:160
msgid "VALUE"
msgstr "WARTOŚĆ"
#: tools/gtk-path-tool-render.c:66 tools/gtk-path-tool-show.c:135
#: tools/gtk-path-tool-render.c:133 tools/gtk-path-tool-show.c:155
msgid "Line width (number)"
msgstr "Szerokość linii (liczba)"
#: tools/gtk-path-tool-render.c:67 tools/gtk-path-tool-show.c:136
#: tools/gtk-path-tool-render.c:134 tools/gtk-path-tool-show.c:156
msgid "Line cap (butt, round, square)"
msgstr "Koniec linii (grubszy koniec, okrągły, kwadratowy)"
#: tools/gtk-path-tool-render.c:68 tools/gtk-path-tool-show.c:137
#: tools/gtk-path-tool-render.c:135 tools/gtk-path-tool-show.c:157
msgid "Line join (miter, miter-clip, round, bevel, arcs)"
msgstr "Złącze linii (kątowe, kątowe przycięte, okrągłe, skośne, łuki)"
#: tools/gtk-path-tool-render.c:69 tools/gtk-path-tool-show.c:138
#: tools/gtk-path-tool-render.c:136 tools/gtk-path-tool-show.c:158
msgid "Miter limit (number)"
msgstr "Ograniczenie kątowych (liczba)"
#: tools/gtk-path-tool-render.c:70 tools/gtk-path-tool-show.c:139
#: tools/gtk-path-tool-render.c:137 tools/gtk-path-tool-show.c:159
msgid "Dash pattern (comma-separated numbers)"
msgstr "Wzór kresek (liczby oddzielone przecinkami)"
#: tools/gtk-path-tool-render.c:71 tools/gtk-path-tool-show.c:140
#: tools/gtk-path-tool-render.c:138 tools/gtk-path-tool-show.c:160
msgid "Dash offset (number)"
msgstr "Wyrównanie kresek (liczba)"
#: tools/gtk-path-tool-render.c:90 tools/gtk-path-tool-show.c:153
#: tools/gtk-path-tool-render.c:161 tools/gtk-path-tool-show.c:172
msgid "Could not initialize windowing system"
msgstr "Nie można zainicjować systemu okien"
#: tools/gtk-path-tool-render.c:97
#: tools/gtk-path-tool-render.c:168
msgid "Render the path to a png image."
msgstr "Rysuje ścieżkę do obrazu PNG."
#: tools/gtk-path-tool-render.c:102 tools/gtk-path-tool-show.c:164
#: tools/gtk-path-tool-render.c:173 tools/gtk-path-tool-show.c:183
msgid "Options related to filling"
msgstr "Opcje związane z wypełnianiem"
#: tools/gtk-path-tool-render.c:103 tools/gtk-path-tool-show.c:165
#: tools/gtk-path-tool-render.c:174 tools/gtk-path-tool-show.c:184
msgid "Show help for fill options"
msgstr "Wyświetla pomoc dla opcji wypełniania"
#: tools/gtk-path-tool-render.c:110 tools/gtk-path-tool-show.c:172
#: tools/gtk-path-tool-render.c:181 tools/gtk-path-tool-show.c:191
msgid "Options related to stroking"
msgstr "Opcje związane z pociąganiem"
#: tools/gtk-path-tool-render.c:111 tools/gtk-path-tool-show.c:173
#: tools/gtk-path-tool-render.c:182 tools/gtk-path-tool-show.c:192
msgid "Show help for stroke options"
msgstr "Wyświetla pomoc dla opcji pociągania"
#: tools/gtk-path-tool-render.c:128 tools/gtk-path-tool-show.c:190
#: tools/gtk-path-tool-render.c:199 tools/gtk-path-tool-show.c:209
msgid "No path specified"
msgstr "Nie podano ścieżki"
#: tools/gtk-path-tool-render.c:134
#: tools/gtk-path-tool-render.c:205
msgid "Can only render a single path"
msgstr "Można narysować tylko jedną ścieżkę"
#: tools/gtk-path-tool-render.c:140 tools/gtk-path-tool-show.c:202
#: tools/gtk-path-tool-render.c:250 tools/gtk-path-tool-show.c:221
msgid "fill rule"
msgstr "reguła wypełniania"
#: tools/gtk-path-tool-render.c:144 tools/gtk-path-tool-show.c:206
#: tools/gtk-path-tool-render.c:255 tools/gtk-path-tool-show.c:226
msgid "line cap"
msgstr "koniec linii"
#: tools/gtk-path-tool-render.c:145 tools/gtk-path-tool-show.c:207
#: tools/gtk-path-tool-render.c:256 tools/gtk-path-tool-show.c:227
msgid "line join"
msgstr "złącze linii"
#: tools/gtk-path-tool-render.c:169 tools/gtk-path-tool-show.c:231
#, c-format
msgid "Failed to parse '%s' as number"
msgstr "Przetworzenie „%s” jako liczby się nie powiodło"
#: tools/gtk-path-tool-render.c:213
#: tools/gtk-path-tool-render.c:310
#, c-format
msgid "Saving png to '%s' failed"
msgstr "Zapisanie obrazu PNG do „%s” się nie powiodło"
#: tools/gtk-path-tool-render.c:220
#: tools/gtk-path-tool-render.c:317
#, c-format
msgid "Output written to '%s'."
msgstr "Wyjście zapisano do „%s”."
#: tools/gtk-path-tool-show.c:43 tools/gtk-path-tool-show.c:78
#: tools/gtk-path-tool-restrict.c:36
msgid "Beginning of segment"
msgstr "Początek segmentu"
#: tools/gtk-path-tool-restrict.c:36 tools/gtk-path-tool-restrict.c:37
msgid "LENGTH"
msgstr "DŁUGOŚĆ"
#: tools/gtk-path-tool-restrict.c:37
msgid "End of segment"
msgstr "Koniec segmentu"
#: tools/gtk-path-tool-restrict.c:51
msgid "Restrict a path to a segment."
msgstr "Ogranicza ścieżkę do segmentu."
#: tools/gtk-path-tool-reverse.c:45
msgid "Reverse a path."
msgstr "Odwraca ścieżkę."
#: tools/gtk-path-tool-show.c:46 tools/gtk-path-tool-show.c:88
msgid "Path Preview"
msgstr "Podgląd ścieżki"
#: tools/gtk-path-tool-show.c:161
#: tools/gtk-path-tool-show.c:180
msgid "Display the path."
msgstr "Wyświetla ścieżkę."
#: tools/gtk-path-tool-show.c:196
#: tools/gtk-path-tool-show.c:215
msgid "Can only show a single path"
msgstr "Można wyświetlić tylko jedną ścieżkę"
@@ -7713,6 +7761,11 @@ msgstr "Możliwe wartości: "
msgid "Could not parse '%s' as color"
msgstr "Nie można przetworzyć „%s” jako kolor"
#: tools/gtk-path-tool-utils.c:163
#, c-format
msgid "Failed to parse '%s' as number"
msgstr "Przetworzenie „%s” jako liczby się nie powiodło"
#: tools/gtk-rendernode-tool.c:35
#, c-format
msgid ""
@@ -7738,37 +7791,37 @@ msgstr ""
" render Wykonuje zrzut ekranu węzła\n"
"\n"
#: tools/gtk-rendernode-tool-info.c:185
#: tools/gtk-rendernode-tool-info.c:187
#, c-format
msgid "Number of nodes: %u\n"
msgstr "Liczba węzłów: %u\n"
#: tools/gtk-rendernode-tool-info.c:192
#: tools/gtk-rendernode-tool-info.c:194
#, c-format
msgid "Depth: %u\n"
msgstr "Głębokość: %u\n"
#: tools/gtk-rendernode-tool-info.c:195
#: tools/gtk-rendernode-tool-info.c:197
#, c-format
msgid "Bounds: %g x %g\n"
msgstr "Granice: %g×%g\n"
#: tools/gtk-rendernode-tool-info.c:196
#: tools/gtk-rendernode-tool-info.c:198
#, c-format
msgid "Origin: %g %g\n"
msgstr "Punkt początkowy: %g %g\n"
#: tools/gtk-rendernode-tool-info.c:217
#: tools/gtk-rendernode-tool-info.c:219
msgid "Provide information about the render node."
msgstr "Podaje informacje o węźle rysowania."
#: tools/gtk-rendernode-tool-info.c:230 tools/gtk-rendernode-tool-render.c:225
#: tools/gtk-rendernode-tool-info.c:232 tools/gtk-rendernode-tool-render.c:225
#: tools/gtk-rendernode-tool-show.c:130
#, c-format
msgid "No .node file specified\n"
msgstr "Nie podano pliku .node\n"
#: tools/gtk-rendernode-tool-info.c:236
#: tools/gtk-rendernode-tool-info.c:238
#, c-format
msgid "Can only accept a single .node file\n"
msgstr "Może przyjąć tylko jeden plik .node\n"
@@ -7818,6 +7871,11 @@ msgstr "Można wyświetlić podgląd tylko jednego pliku .node\n"
msgid "Error at %s: %s\n"
msgstr "Błąd w %s: %s\n"
#: tools/gtk-rendernode-tool-utils.c:69
#, c-format
msgid "Failed to load node file: %s\n"
msgstr "Wczytanie pliku węzła się nie powiodło: %s\n"
#: tools/updateiconcache.c:1391
#, c-format
msgid "Failed to write header\n"
+1042 -829
View File
File diff suppressed because it is too large Load Diff
+1185 -901
View File
File diff suppressed because it is too large Load Diff
+266 -200
View File
File diff suppressed because it is too large Load Diff
+1205 -701
View File
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,6 @@
repeating-linear-gradient {
bounds: 0 0 50 50;
start: 0 0;
end: 0 50;
stops: 0.5 rgb(255,0,0), 0.5 rgb(0,255,0);
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Some files were not shown because too many files have changed in this diff Show More