Compare commits

...

110 Commits

Author SHA1 Message Date
Matthias Clasen c1e6e8e2a7 Add more fill and stroke node tests 2023-08-26 00:48:31 -04:00
Matthias Clasen 61756ab39d Document node format for stroke and fill nodes 2023-08-26 00:48:31 -04:00
Matthias Clasen ca188b41ae post-release version bump 2023-08-25 22:29:09 -04:00
Matthias Clasen 01b9997590 4.13.0 2023-08-25 22:21:27 -04:00
Matthias Clasen 677e19042d Docs: Cosmetics 2023-08-25 22:21:27 -04:00
Matthias Clasen bd79f61cc5 pathpoint: Update the docs
We have gained some more ways of getting points.
2023-08-25 22:03:42 -04:00
Matthias Clasen 361cdecfe4 Merge branch 'path-measure-reredone' into 'main'
Add GskPathMeasure

See merge request GNOME/gtk!6326
2023-08-26 01:05:19 +00:00
Matthias Clasen 581ad5fc04 Make curve tests more robust
Add a few fudge factors that let these
tests survive extended runs.
2023-08-25 20:23:08 -04:00
Matthias Clasen ff40dcffec Make the measure tests waste less time
No need to produce multiple contours, when
the test is just about splitting a single
curve.
2023-08-25 20:23:08 -04:00
Matthias Clasen eb2fa4195a Make the measure tests run in ci
Marking them as slow has the unintended
side-effect of keeping them from running.
2023-08-25 20:23:08 -04:00
Benjamin Otte e2d2b57f0e demos: Add a text-on-path demo 2023-08-25 20:23:08 -04:00
Matthias Clasen 6c1a128ea3 Make the map demo more interesting
Add marching arrows to it.

With this, it can also serve as a performance
test for rendering medium complexity paths.
2023-08-25 20:23:08 -04:00
Matthias Clasen cfaa31eeb8 Expand docs for GskPathMeasure 2023-08-25 20:23:08 -04:00
Matthias Clasen 2097b15f9c Add randomized measure tests
Test that lengths behave as expected when
we split paths, do roundtrips through points,
and subset paths.
2023-08-25 20:16:49 -04:00
Matthias Clasen 46a8f57735 Add tests for path length 2023-08-25 20:16:49 -04:00
Matthias Clasen 2e5639a077 Add a circle test 2023-08-25 20:16:49 -04:00
Matthias Clasen 007cfeac94 Add GskPathMeasure
GskPathMeasure is the public API for path lengths.
2023-08-25 20:16:49 -04:00
Matthias Clasen 553499522c contour: Add measure API
In order to compute path lengths efficiently, we need
to cache lookup tables. This commit adds API to let
contours allocate and free such measure data, as well
as API to use the data to go length -> point and
vice versa.
2023-08-25 20:16:49 -04:00
Benjamin Otte 81821978ae Merge branch 'wip/otte/for-main' into 'main'
gltexture: Restore previous GL context

See merge request GNOME/gtk!6335
2023-08-25 21:44:17 +00:00
Matthias Clasen 787b1a661e curve: Add tests for length
Add some tests for gsk_curve_get_length.
2023-08-25 16:13:36 -04:00
Matthias Clasen 04e6fc3f74 curve: Add length computation
Add api to go t<>length.

The code here is inspired by
https://pomax.github.io/bezierinfo/#arclength
2023-08-25 16:13:36 -04:00
Benjamin Otte 54d2f0063a Merge branch 'replay' into 'main'
Node replay tests

See merge request GNOME/gtk!6299
2023-08-25 19:45:34 +00:00
Benjamin Otte ae7ec40cf2 rendernodeparser: Generate better default child
... for fill and stroke nodes.

It's most likely we want the path bounds (or path stroke bounds),
so make the parser use those by default.
2023-08-25 21:12:12 +02:00
Matthias Clasen d586a5c67c Merge branch 'fix-gears-demo' into 'main'
demo: Fix a bug without GL

Closes #6059

See merge request GNOME/gtk!6333
2023-08-25 14:34:13 +00:00
Matthias Clasen c97dc6e903 Merge branch 'conics-revisited' into 'main'
path: Switch back to conics

See merge request GNOME/gtk!6332
2023-08-25 14:26:33 +00:00
Matthias Clasen eec90d1026 pathbuilder: Add rel-variants for arc-to
Add rel-variants for all our arc-to APIs. This is
a pretty harmless addition, and it is more consistent
to have these for all ..._to functions.
2023-08-25 09:45:45 -04:00
Matthias Clasen f4fb4d04e5 Some pathbuilder doc clarifications
Mention the end point of the html arc-to call.
2023-08-25 09:37:07 -04:00
Matthias Clasen 3283157352 Bring arc_to back as convenience API
It is our main use of conics, so make it an API,
and use it internally.
2023-08-25 09:31:19 -04:00
Sergey Bugaev d07a6b8566 snapshot, gsktransform: Mention that rotation happens around (0, 0)
...and not around the center of the render node, as one could expect
given that the render node syntax for rotation, transform: rotate(90);,
happens to match the CSS syntax for the same thing, and CSS does rotate
around the center by default.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2023-08-25 15:54:05 +03:00
Sergey Bugaev 4e8e59cd58 snapshot: Fix push_repeat () with empty child bounds
The logic would confuse empty child bounds (in which case nothing should
get rendered) with NULL child bounds (in which case the child node's own
bounds should get used). In fact, if the child bounds are empty, we can
discard the descendant render nodes completely, getting a nice little
optimization.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2023-08-25 15:54:05 +03:00
Sergey Bugaev 9f811ccee5 testsuite: Add color-matrix-merge testcase
This tests the merging of nested color matrix nodes feature of
GtkSnapshot, which was broken before commit 082fdfdb24.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2023-08-25 15:54:05 +03:00
Sergey Bugaev 6cd6da050b testsuite: Add render node replay tests
This takes a render node tree and "replays" it by using the GtkSnapshot
machinery. We don't necesserily expect to get back an exactly equal
render node tree back, since GtkSnapshot applies various small
optimizations where possible, but the original and the replayed nodes
should render to identical textures.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2023-08-25 15:54:05 +03:00
Matthias Clasen a906dbea35 demo: Fix a bug without GL
The gears widget was just not unrealizing properly
when GL is not available. Fix that.

Fixes: #6059
2023-08-25 08:37:22 -04:00
Matthias Clasen 5bc82f4141 Change curve derivative api
We don't need to have the derivative as a curve,
it is enough for us to compute values of the
derivative at a given t, which we can also do
for conics.
2023-08-25 07:33:16 -04:00
Matthias Clasen 25e6231a88 path: Switch back to conics
Arcs were appealing, but they have a fatal flaw: we can't
split our arcs without changing the ellipse they trace.
That could be fixed by adding an extra parameter, but then
it is no longer any better than conics.

So switch back to conics, which have the advantage that they
are used elsewhere.
2023-08-25 07:33:16 -04:00
Matthias Clasen 650e4b1920 Merge branch 'matthiasc/for-main' into 'main'
path docs: Clarify curvature

See merge request GNOME/gtk!6331
2023-08-24 19:55:36 +00:00
Matthias Clasen 5dc0cbc20f Expand the path docs a bit 2023-08-24 15:00:14 -04:00
Matthias Clasen e1faf28310 Make curvature api more flexible
Add an extra direction argument to get_curvature to
allow picking the limit on either side, for sharp turns.

Update all callers.
2023-08-24 14:32:33 -04:00
Matthias Clasen 854c695153 pathpoint docs: Fix a link
Links gsk->gtk must be done manually, since we
don't have a dependency.
2023-08-24 13:41:39 -04:00
Matthias Clasen ebd4ceca15 path docs: Clarify curvature
The curvature of lines is zero, not infinite.
2023-08-24 11:15:51 -04:00
Matthias Clasen d873643407 path docs: Add another illustration 2023-08-24 11:09:28 -04:00
Matthias Clasen 8a789d0234 path docs: Cosmetics 2023-08-24 10:54:23 -04:00
Emmanuele Bassi 286b4cbc72 Merge branch 'macos_ci' into 'main'
interim solution for macOS CI

See merge request GNOME/gtk!6274
2023-08-24 14:10:03 +00:00
René de Hesselle b4428029af Change workflow to enable MR pipelines
This makes it possible to have macOS CI run for everything inside the
main repository and for merge requests.
2023-08-24 15:30:03 +02:00
René de Hesselle 9aeb5be8ad gdk: Use subpixel_layout on macOS 2023-08-24 15:30:03 +02:00
René de Hesselle 007dd55a71 Re-enable macOS CI on new self-hosted runner 2023-08-24 15:30:03 +02:00
Matthias Clasen 7a05e40ce7 Merge branch 'matthiasc/for-main' into 'main'
Add some more arc tests

See merge request GNOME/gtk!6330
2023-08-24 12:20:13 +00:00
Matthias Clasen 8d0654db6b Add some more arc tests 2023-08-24 07:40:05 -04:00
Matthias Clasen 63d5615fe7 Merge branch 'dboles/issue6001-ShortcutsWindow-programmatic' into 'main'
Add API to programmatically build ShortcutsWindow

Closes #6001

See merge request GNOME/gtk!6249
2023-08-24 10:40:34 +00:00
Matthias Clasen 37d18816be menubutton: Don't assume the root is a window
The only thing this assumption does is cause
criticals, so remove it.

Fixes: #6055
2023-08-24 06:30:55 -04:00
Matthias Clasen f1de7a524c Merge branch 'matthiasc/for-main' into 'main'
demo cosmetics

See merge request GNOME/gtk!6329
2023-08-24 10:17:44 +00:00
Fran Dieguez 644692a2e0 Update Galician translation 2023-08-24 06:19:48 +00:00
Matthias Clasen da2e8b78c2 Merge branch 'matthiasc/for-main' into 'main'
demo cosmetics

See merge request GNOME/gtk!6329
2023-08-24 03:47:00 +00:00
Matthias Clasen 0b5a6ecbff demos: Cosmetics 2023-08-23 23:20:17 -04:00
Matthias Clasen 9a6aac0459 path spinner demo: Don't crash 2023-08-23 23:18:59 -04:00
Benjamin Otte 8aaecc3416 gltexture: Restore previous GL context
Texture downloads can be initiated due to the weirdest reasons - and if
they cause a GL context to be changed, it'd be basically unpredictable
when the GL context changes.

An example is the Cairo renderer - if it needs to draw a GL texture, it
will download it.

Now that no longer changes the GL context.
2023-08-24 05:00:29 +02:00
Matthias Clasen d3f9b3e28a Merge branch 'matthiasc/for-main' into 'main'
arc: Fix the derivative

See merge request GNOME/gtk!6328
2023-08-24 02:45:58 +00:00
Matthias Clasen 4229a37e90 arc: Fix the derivative
Scale the derivative such that computing the arc length
of a unit quarter circle wil produce the expected result
of PI/2.
2023-08-23 22:18:52 -04:00
Matthias Clasen 12297fd88a arc curve: Simplify derivative 2023-08-23 22:11:22 -04:00
Matthias Clasen 7943610066 curve: Fix arc decomposition 2023-08-23 22:11:15 -04:00
Matthias Clasen e19246d2db tests: Include arcs in curve tests 2023-08-23 22:10:51 -04:00
Matthias Clasen e70117bd9f Merge branch 'mcatanzaro/#6056' into 'main'
notebook: fix critical when switching page

Closes #6056

See merge request GNOME/gtk!6327
2023-08-24 01:09:19 +00:00
Michael Catanzaro 20c4e24b74 notebook: fix critical when switching page
It's expected that gtk_widget_get_root() will return NULL if the widget
tree does not contain a root widget. I don't know what that means or why
it happens, but it's true in gnome-control-center's network panel when
displaying the OpenVPN configuration dialog. We need to handle it.

Fixes #6056
2023-08-23 15:51:08 -05:00
Matthias Clasen 3c5efbc77e Merge branch 'wip/matthiasc/arcs' into 'main'
path: Add arcs

See merge request GNOME/gtk!6313
2023-08-23 19:17:01 +00:00
Matthias Clasen f6c2b6bb88 Make foreach work efficiently with arcs 2023-08-23 14:51:31 -04:00
Matthias Clasen 4ab03e79b7 Drop some unnecessary code
We tell path_foreach to split into lines or cubics,
so no point in having code to handle quads and arcs.
2023-08-23 14:33:25 -04:00
Matthias Clasen 7a12abdea3 Incorporate review feedback 2023-08-23 14:16:43 -04:00
Matthias Clasen 36ca1f10dc Add an arc demo
Make a circular spinner to see how well arcs
do for circles.
2023-08-23 13:45:12 -04:00
Matthias Clasen 07a92c1690 Merge branch 'matthiasc/for-main' into 'main'
docs: Fix gsk->gtk links

See merge request GNOME/gtk!6324
2023-08-23 16:45:26 +00:00
Matthias Clasen 0f7b9e686c Add a rounded rect test
This checks that our path-in-fill computations
agree with rounded_rect_contains_point. Sadly,
they don't do that, 100%.
2023-08-23 12:43:52 -04:00
Matthias Clasen 71584107b0 Add gsk_path_builder_html_arc_to
This one draws circular arcs with a given radius.
2023-08-23 12:43:52 -04:00
Matthias Clasen 88c0ace644 Make gsk_path_builder_svg_arc_to public
This is useful to port SVG paths using this syntax.
2023-08-23 12:43:52 -04:00
Matthias Clasen d33ed4f9ab path: Add elliptical arcs
Add a new curve type for elliptical arcs
and use it for rounded rectangles and circles.
We use the 'E' command to represent elliptical
arcs in serialized paths.
2023-08-23 12:43:52 -04:00
Matthias Clasen a63af177a4 docs: Fix gsk->gtk links
gi-docgen can't handle these, since we don't have
a dependency.
2023-08-23 11:38:13 -04:00
Piotr Drąg 43c8e136b5 Update Polish translation 2023-08-23 16:43:05 +02:00
Matthias Clasen efd597c6ed Merge branch 'default-get-current-image' into 'main'
Implement gdk_paintable_default_get_current_image ()

See merge request GNOME/gtk!6303
2023-08-23 10:53:12 +00:00
Fran Dieguez 024a753a6a Update Galician translation 2023-08-23 07:24:01 +00:00
Danial Behzadi e1dd3fb801 Update Persian translation 2023-08-23 00:18:33 +00:00
Ekaterine Papava 82011569ce Update Georgian translation 2023-08-22 21:14:18 +00:00
Sabri Ünal 747c9c4f94 Update Turkish translation 2023-08-22 20:18:57 +00:00
Matthias Clasen 7d7a090875 Merge branch 'wip/smcv/i387' into 'main'
tests: Accept slightly different numeric results

Closes #6051

See merge request GNOME/gtk!6320
2023-08-22 17:34:10 +00:00
Simon McVittie 0f125aad90 tests: Accept slightly different numeric results
FLT_EPSILON is the distance between 1.0 and the next distinct floating
point number, and doesn't necessarily have anything to do with the
precision we can expect from a series of floating-point calculations.
Experimentally, 1e-6 is achievable, even on platforms with unusual
floating point implementations like i387.

Resolves: https://gitlab.gnome.org/GNOME/gtk/-/issues/6051
Bug-Debian: https://bugs.debian.org/1050076
Signed-off-by: Simon McVittie <smcv@debian.org>
2023-08-22 17:24:17 +01:00
Matthias Clasen a7d5796750 Merge branch 'path-tool-tweak' into 'main'
path-tool: Reorganize options

See merge request GNOME/gtk!6323
2023-08-22 16:19:19 +00:00
Matthias Clasen 79e132ab7b path-tool: Reorganize options
Put fill and stroke options into their own group.
This helps produce understandable --help output.
2023-08-22 09:56:43 -04:00
Danial Behzadi 85957b5d3e Update Persian translation 2023-08-22 13:39:46 +00:00
Matthias Clasen 373972b8ca Merge branch 'fix-wayland-crash' into 'main'
wayland: Don't assume the shell protocol

Closes #6048

See merge request GNOME/gtk!6322
2023-08-22 13:13:51 +00:00
Matthias Clasen 30e6d70b14 Merge branch 'matthiasc/for-main' into 'main'
docs: Tweaks

See merge request GNOME/gtk!6321
2023-08-22 13:07:42 +00:00
Matthias Clasen c78b34649b wayland: Don't assume the shell protocol
The gtk_shell proxy will be NULL if the compositor
is not gnome-shell. Handle that without crashing.

Fixes: #6048
2023-08-22 08:27:23 -04:00
Matthias Clasen b3fe68ca95 docs: Tweaks 2023-08-22 07:56:27 -04:00
Daniel Mustieles 417888f847 Updated Spanish translation 2023-08-22 13:25:53 +02:00
Benjamin Otte de8fdd822c Merge branch 'wip/otte/for-main' into 'main'
widget: Remove unused headers from gtkwidget.h

See merge request GNOME/gtk!6319
2023-08-22 07:38:57 +00:00
Matthias Clasen ee8e6ac546 Merge branch 'matthiasc/for-main' into 'main'
Make sure stroke bounds are big enough

See merge request GNOME/gtk!6318
2023-08-22 05:36:16 +00:00
Matthias Clasen 486674927a Make sure stroke bounds are big enough
Our standard 'empty path' in gtk4-node-editor
was getting its pointy corners cut off.
2023-08-21 23:59:08 -04:00
Matthias Clasen acf9612ed8 docs: Start a section on paths 2023-08-21 23:59:08 -04:00
Matthias Clasen 8c664b669c Merge branch 'matthiasc/for-main' into 'main'
docs: Drop a nonexisting enum value

See merge request GNOME/gtk!6317
2023-08-22 03:47:30 +00:00
Matthias Clasen b367bf83b4 docs: Tweaks 2023-08-21 22:40:22 -04:00
Matthias Clasen b84f60877d docs: Drop a nonexisting enum value 2023-08-21 21:52:53 -04:00
Matthias Clasen 8a84024a54 Merge branch 'bilelmoussaoui/gi' into 'main'
gi: Fix missing namespace

See merge request GNOME/gtk!6316
2023-08-22 00:47:05 +00:00
Bilal Elmoussaoui 56cb614f79 gi: Fix missing namespace 2023-08-21 21:11:12 +00:00
Matthias Clasen 957d8845fd Merge branch 'kabus/x11-clipboard-leak' into 'main'
gdk/x11/clipboard: Fix Slist leak

See merge request GNOME/gtk!6314
2023-08-21 20:39:29 +00:00
Khalid Abu Shawarib 79fa785dbc gdk/x11/clipboard: Fix Slist leak 2023-08-21 20:32:42 +03:00
Benjamin Otte 29cdac18e8 rendernodeparser: Handle dashing in strokes
That part of the original MR got lost while refactoring.

Put it back.
2023-08-21 05:23:44 +02:00
Benjamin Otte 418f6b35af gsk: Add gsk_rect_to_float()
... and use it.
2023-08-21 05:23:42 +02:00
Benjamin Otte 96a6e05f0b build: Add -Woverride-init
That's a gcc warning (clang has the equivalent -Winitializer-overrides,
but that one is included in -Wall) that complains about things like:

  VkOffset3D offset = { .x = pt.x, .x = pt.y, .y = 0 };

So you don't have to spend a few hours trying to understand what's going
on before realizing your copy/paste skills are substandard.
2023-08-21 05:20:31 +02:00
Benjamin Otte d665d2fb89 vulkan: Add nonuniformEXT() where needed
The magical term to know about (because the GLSL compiler or the
validation layers sure as hell don't) is:

  "dynamically uniform expression"

because if you don't have that when indexing a texture or buffer array,
you need to add nonuniformEXT() around the index variable.

Fixes the close icon on AMD having glitches of the previous icon visible
in some pixels.
2023-08-21 05:19:44 +02:00
Benjamin Otte 8862666b5a build: GSK doesn't depend on gdk-pixbuf 2023-08-21 05:19:37 +02:00
Benjamin Otte 3adf02445f build: Don't use configure_file() when custom_target() works
These two files don't need to be built when configuring, they are only
needed during build.
2023-08-21 05:19:37 +02:00
Benjamin Otte bfdd325d36 widget: Remove unused headers from gtkwidget.h
... and put them back in places where they are needed.
2023-08-21 05:19:37 +02:00
Sergey Bugaev e45cba13ed paintable: Implement gdk_paintable_default_get_current_image ()
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2023-08-18 11:10:22 +03:00
Daniel Boles eebe370e0a Add API to programmatically build ShortcutsWindow
and friends. This used to work OK via Container.add() but stopped
working in GTK4. While we have some ways left to TRY to add children
(via GtkWindow and Box), those don't work and result in broken layout
and assertion failures. Add basic API that can allow this to work again.

Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/6001
2023-08-07 11:37:10 +01:00
106 changed files with 6825 additions and 865 deletions
+28 -9
View File
@@ -30,8 +30,16 @@ variables:
workflow:
rules:
- if: $CI_COMMIT_TAG
# run merge request pipelines
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
# do not run branch pipelines if corresponding merge requests exist...
# (this avoids duplicate pipelines)
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never
# ...but otherwise run branch pipelines
- if: $CI_COMMIT_BRANCH
# run tag pipelines
- if: $CI_COMMIT_TAG
default:
retry:
@@ -197,21 +205,32 @@ msys2-mingw64:
paths:
- "${CI_PROJECT_DIR}/_build/gtkdll.tar.gz"
macos:
# Sadly, this fails regularly, and its failure is never enlightening
allow_failure: true
macos-x86_64:
rules:
# run merge request pipelines
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
# do not run in forks
- if: $CI_PROJECT_NAMESPACE == "GNOME"
stage: build
tags:
- macos
- macosintel
needs: []
variables:
MESON_FORCE_BACKTRACKE: 1
TMPDIR: /Users/Shared/work/tmp
SDKROOT: /opt/sdks/MacOSX10.13.4.sdk
CCACHE_DIR: /Users/Shared/work/ccache
PIP_CACHE_DIR: /Users/Shared/build/cache
PIPENV_CACHE_DIR: $PIP_CACHE_DIR
PYTHONPYCACHEPREFIX: $PIP_CACHE_DIR
before_script:
- bash .gitlab-ci/show-info-osx.sh
- pip3 install --user meson~=1.0
- pip3 install --user ninja
- export PATH=/Users/gitlabrunner/Library/Python/3.7/bin:$PATH
- export MESON_FORCE_BACKTRACE=1
- python3 -m venv .venv
- ln -s /opt/cmake/CMake.app/Contents/bin/cmake .venv/bin
- ln -s /opt/ccache/ccache .venv/bin
- source .venv/bin/activate
- pip3 install meson==1.2.0
- pip3 install ninja==1.11.1
script:
- meson setup ${COMMON_MESON_FLAGS}
-Dx11-backend=false
+76 -1
View File
@@ -1,6 +1,81 @@
Overview of Changes in 4.13.0, xx-xx-xxxx
Overview of Changes in 4.13.1, xx-xx-xxxx
=========================================
Overview of Changes in 4.13.0, 25-08-2023
=========================================
* GskPath, GskPathBuilder, GskPathMeasure:
Data types and APIs for path rendering. These APIs are still
considered experimental, and may change until 4.14. Please try
them out and give us feedback. Documentation can be found
here: https://docs.gtk.org/gsk4/paths.html
* GtkGridView:
- Fix a crash when scrolling
* GtkColumnView:
- Fix a refcounting issue in the new scroll_to api
* GtkTreeView
- Fix style classes for sort arrows
* GtkEntry:
- Improve tracking of user changes (for undo)
* GtkNotebook:
- Fix a critical when switching pages
* GtkColor/FontDialogButton:
- Make these widgets activatable
* GtkMenuButton:
- Fix problems with focus handling
- Fix problems with DND
- Make flags a settable property
* GtkShortcutsWindow:
- Add API to build shortcuts windows programmatically
* Printing
- Fix the cpdb backend build
* MacOS:
- Make file filters work again
* GSK:
- Fix issues with color matrix nodes
* Wayland:
- Fix a crash with compositors other than gnome-shell
* Deprecations:
- Remaining GtkTreeModel-related types
* Demos:
- Add a few path demos to gtk4-demo
* Tools:
- gtk4-path-tool provides a commandline interface for paths
* Translation updates:
Basque
Catalan
Finnish
Galician
Georgian
German
Greek
Indonesian
Kazakh
Persian
Polish
Romanian
Spanish
Swedish
Turkish
Ukrainian
Overview of Changes in 4.12.0, 05-08-2023
=========================================
+5
View File
@@ -336,7 +336,9 @@
<file>panes.c</file>
<file>password_entry.c</file>
<file>path_fill.c</file>
<file>path_spinner.c</file>
<file>path_walk.c</file>
<file>path_text.c</file>
<file>peg_solitaire.c</file>
<file>pickers.c</file>
<file>printing.c</file>
@@ -426,6 +428,9 @@
<file>path_walk.ui</file>
<file compressed="true">path_world.txt</file>
</gresource>
<gresource prefix="/path_text">
<file>path_text.ui</file>
</gresource>
<gresource prefix="/org/gtk/Demo4">
<file>icons/16x16/actions/application-exit.png</file>
<file>icons/16x16/actions/document-new.png</file>
+14 -14
View File
@@ -840,24 +840,24 @@ gtk_gears_unrealize (GtkWidget *widget)
GtkGearsPrivate *priv = gtk_gears_get_instance_private ((GtkGears *) widget);
gtk_gl_area_make_current (glarea);
if (gtk_gl_area_get_error (glarea) != NULL)
return;
if (gtk_gl_area_get_error (glarea) == NULL)
{
/* Release the resources associated with OpenGL */
if (priv->gear_vbo[0] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[0]));
/* Release the resources associated with OpenGL */
if (priv->gear_vbo[0] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[0]));
if (priv->gear_vbo[1] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[1]));
if (priv->gear_vbo[1] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[1]));
if (priv->gear_vbo[2] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[2]));
if (priv->gear_vbo[2] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[2]));
if (priv->vao != 0)
glDeleteVertexArrays (1, &priv->vao);
if (priv->vao != 0)
glDeleteVertexArrays (1, &priv->vao);
if (priv->program != 0)
glDeleteProgram (priv->program);
if (priv->program != 0)
glDeleteProgram (priv->program);
}
priv->ModelViewProjectionMatrix_location = 0;
priv->NormalMatrix_location = 0;
+2
View File
@@ -73,7 +73,9 @@ demos = files([
'panes.c',
'password_entry.c',
'path_fill.c',
'path_spinner.c',
'path_walk.c',
'path_text.c',
'peg_solitaire.c',
'pickers.c',
'printing.c',
+1 -1
View File
@@ -177,7 +177,7 @@ do_path_fill (GtkWidget *do_widget)
window = gtk_window_new ();
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
gtk_window_set_title (GTK_WINDOW (window), "Path Fill");
gtk_window_set_title (GTK_WINDOW (window), "Fill and Stroke");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
paintable = gtk_logo_paintable_new ();
+331
View File
@@ -0,0 +1,331 @@
/* Path/Spinner
*
* This demo shows how to use GskPath to draw a simple animation
* that could be used as a spinner.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "paintable.h"
#define GTK_TYPE_SPINNER_PAINTABLE (gtk_spinner_paintable_get_type ())
G_DECLARE_FINAL_TYPE (GtkSpinnerPaintable, gtk_spinner_paintable, GTK, SPINNER_PAINTABLE, GObject)
struct _GtkSpinnerPaintable
{
GObject parent_instance;
gint64 start_time;
int width;
double angle;
double completion;
GskPath *circle;
GskPath *path;
GskStroke *stroke;
GdkRGBA color;
GdkRGBA circle_color;
#ifdef SHOW_CONTROLS
GskPath *controls;
GdkRGBA control_color;
#endif
};
struct _GtkSpinnerPaintableClass
{
GObjectClass parent_class;
};
static int
gtk_spinner_paintable_get_intrinsic_width (GdkPaintable *paintable)
{
GtkSpinnerPaintable *self = GTK_SPINNER_PAINTABLE (paintable);
return self->width;
}
static int
gtk_spinner_paintable_get_intrinsic_height (GdkPaintable *paintable)
{
GtkSpinnerPaintable *self = GTK_SPINNER_PAINTABLE (paintable);
return self->width;
}
static void
gtk_spinner_paintable_snapshot (GdkPaintable *paintable,
GdkSnapshot *snapshot,
double width,
double height)
{
GtkSpinnerPaintable *self = GTK_SPINNER_PAINTABLE (paintable);
gtk_snapshot_append_stroke (snapshot, self->circle, self->stroke, &self->circle_color);
gtk_snapshot_append_stroke (snapshot, self->path, self->stroke, &self->color);
#ifdef SHOW_CONTROLS
GskStroke *stroke = gsk_stroke_new (1);
gtk_snapshot_append_stroke (snapshot, self->controls, stroke, &self->control_color);
gsk_stroke_free (stroke);
#endif
}
static GdkPaintableFlags
gtk_spinner_paintable_get_flags (GdkPaintable *paintable)
{
return GDK_PAINTABLE_STATIC_SIZE;
}
static void
gtk_spinner_paintable_paintable_init (GdkPaintableInterface *iface)
{
iface->get_intrinsic_width = gtk_spinner_paintable_get_intrinsic_width;
iface->get_intrinsic_height = gtk_spinner_paintable_get_intrinsic_height;
iface->snapshot = gtk_spinner_paintable_snapshot;
iface->get_flags = gtk_spinner_paintable_get_flags;
}
/* When defining the GType, we need to implement the GdkPaintable interface */
G_DEFINE_TYPE_WITH_CODE (GtkSpinnerPaintable, gtk_spinner_paintable, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
gtk_spinner_paintable_paintable_init))
static void
gtk_spinner_paintable_dispose (GObject *object)
{
GtkSpinnerPaintable *self = GTK_SPINNER_PAINTABLE (object);
gsk_path_unref (self->circle);
gsk_path_unref (self->path);
#ifdef SHOW_CONTROLS
gsk_path_unref (self->controls);
#endif
gsk_stroke_free (self->stroke);
G_OBJECT_CLASS (gtk_spinner_paintable_parent_class)->dispose (object);
}
static void
gtk_spinner_paintable_class_init (GtkSpinnerPaintableClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gtk_spinner_paintable_dispose;
}
static void
gtk_spinner_paintable_init (GtkSpinnerPaintable *self)
{
}
static GdkPaintable *
gtk_spinner_paintable_new (void)
{
GtkSpinnerPaintable *self;
GskPathBuilder *builder;
self = g_object_new (GTK_TYPE_SPINNER_PAINTABLE, NULL);
builder = gsk_path_builder_new ();
gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (50, 50), 40);
self->circle = gsk_path_builder_free_to_path (builder);
self->width = 100;
self->angle = 0;
self->completion = 1;
gdk_rgba_parse (&self->color, "green");
gdk_rgba_parse (&self->circle_color, "lightgray");
#ifdef SHOW_CONTROLS
gdk_rgba_parse (&self->control_color, "black");
#endif
self->stroke = gsk_stroke_new (5);
return GDK_PAINTABLE (self);
}
#ifdef SHOW_CONTROLS
static gboolean
add_controls (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
gpointer data)
{
GskPathBuilder *builder = data;
switch (op)
{
case GSK_PATH_MOVE:
gsk_path_builder_move_to (builder, pts[0].x, pts[0].y);
break;
case GSK_PATH_CLOSE:
case GSK_PATH_LINE:
gsk_path_builder_line_to (builder, pts[1].x, pts[1].y);
break;
case GSK_PATH_QUAD:
case GSK_PATH_ARC:
gsk_path_builder_line_to (builder, pts[1].x, pts[1].y);
gsk_path_builder_line_to (builder, pts[2].x, pts[2].y);
break;
case GSK_PATH_CUBIC:
gsk_path_builder_line_to (builder, pts[1].x, pts[1].y);
gsk_path_builder_line_to (builder, pts[2].x, pts[2].y);
gsk_path_builder_line_to (builder, pts[3].x, pts[3].y);
break;
default:
g_assert_not_reached ();
}
return TRUE;
}
#endif
static void
update_path (GtkSpinnerPaintable *self)
{
GskPathBuilder *builder;
GskPathPoint start, end;
GskTransform *t;
graphene_point_t p, 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);
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);
builder = gsk_path_builder_new ();
gsk_path_builder_add_segment (builder, self->circle, &start, &end);
self->path = gsk_path_builder_free_to_path (builder);
#ifdef SHOW_CONTROLS
g_clear_pointer (&self->controls, gsk_path_unref);
builder = gsk_path_builder_new ();
gsk_path_foreach (self->path, -1, add_controls, builder);
self->controls = gsk_path_builder_free_to_path (builder);
#endif
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
}
static void
gtk_spinner_paintable_set_completion (GtkSpinnerPaintable *self,
float completion)
{
self->completion = CLAMP (completion, 0, 100);
update_path (self);
}
static float
gtk_spinner_paintable_get_completion (GtkSpinnerPaintable *self)
{
return self->completion;
}
static void
gtk_spinner_paintable_set_frame_time (GtkSpinnerPaintable *self,
gint64 time)
{
double delta;
if (self->start_time == 0)
self->start_time = time;
delta = (time - self->start_time) / (double) G_TIME_SPAN_SECOND;
self->angle = fmod (60 * delta, 360);
update_path (self);
}
static gboolean
tick_cb (GtkWidget *widget,
GdkFrameClock *clock,
gpointer data)
{
GtkSpinnerPaintable *self = data;
gtk_spinner_paintable_set_frame_time (self, gdk_frame_clock_get_frame_time (clock));
return G_SOURCE_CONTINUE;
}
static gboolean
progress_timeout (gpointer data)
{
GtkSpinnerPaintable *self = data;
static float progress_delta = 0.5;
float progress;
progress = gtk_spinner_paintable_get_completion (self);
if (progress >= 100 || progress <= 0)
progress_delta = -progress_delta;
gtk_spinner_paintable_set_completion (self, progress + progress_delta);
return G_SOURCE_CONTINUE;
}
static void
unset_timeout (gpointer data)
{
g_source_remove (GPOINTER_TO_UINT (data));
}
GtkWidget *
do_path_spinner (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkWidget *picture;
GdkPaintable *paintable;
guint timeout_id;
window = gtk_window_new ();
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
gtk_window_set_title (GTK_WINDOW (window), "Spinner");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
paintable = gtk_spinner_paintable_new ();
picture = gtk_picture_new_for_paintable (paintable);
gtk_picture_set_content_fit (GTK_PICTURE (picture), GTK_CONTENT_FIT_CONTAIN);
gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE);
g_object_unref (paintable);
gtk_widget_add_tick_callback (picture, tick_cb, paintable, NULL);
timeout_id = g_timeout_add (100, progress_timeout, paintable);
g_object_set_data_full (G_OBJECT (picture), "timeout", GUINT_TO_POINTER (timeout_id), unset_timeout);
gtk_window_set_child (GTK_WINDOW (window), picture);
}
if (!gtk_widget_get_visible (window))
gtk_window_present (GTK_WINDOW (window));
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}
+586
View File
@@ -0,0 +1,586 @@
/* Path/Text
*
* This demo shows how to use GskPath to transform a path along another path.
*
* It also demonstrates that paths can be filled with more interesting
* content than just plain colors.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#define GTK_TYPE_PATH_WIDGET (gtk_path_widget_get_type ())
G_DECLARE_FINAL_TYPE (GtkPathWidget, gtk_path_widget, GTK, PATH_WIDGET, GtkWidget)
#define POINT_SIZE 8
enum {
PROP_0,
PROP_TEXT,
PROP_EDITABLE,
N_PROPS
};
struct _GtkPathWidget
{
GtkWidget parent_instance;
char *text;
gboolean editable;
graphene_point_t points[4];
guint active_point;
GskPath *line_path;
GskPath *text_path;
GdkPaintable *background;
};
struct _GtkPathWidgetClass
{
GtkWidgetClass parent_class;
};
static GParamSpec *properties[N_PROPS] = { NULL, };
G_DEFINE_TYPE (GtkPathWidget, gtk_path_widget, GTK_TYPE_WIDGET)
static GskPath *
create_path_from_text (GtkWidget *widget,
const char *text,
graphene_point_t *out_offset)
{
PangoLayout *layout;
PangoFontDescription *desc;
GskPathBuilder *builder;
GskPath *result;
layout = gtk_widget_create_pango_layout (widget, text);
desc = pango_font_description_from_string ("sans bold 36");
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
builder = gsk_path_builder_new ();
gsk_path_builder_add_layout (builder, layout);
result = gsk_path_builder_free_to_path (builder);
if (out_offset)
graphene_point_init (out_offset, 0, - pango_layout_get_baseline (layout) / (double) PANGO_SCALE);
g_object_unref (layout);
return result;
}
typedef struct
{
GskPathMeasure *measure;
GskPathBuilder *builder;
graphene_point_t offset;
double scale;
} GtkPathTransform;
static void
gtk_path_transform_point (GskPathMeasure *measure,
const graphene_point_t *pt,
const graphene_point_t *offset,
float scale,
graphene_point_t *res)
{
graphene_vec2_t tangent;
GskPathPoint point;
if (gsk_path_measure_get_point (measure, (pt->x + offset->x) * scale, &point))
{
GskPath *path = gsk_path_measure_get_path (measure);
gsk_path_point_get_position (&point, path, res);
gsk_path_point_get_tangent (&point, path, GSK_PATH_TO_END, &tangent);
res->x -= (pt->y + offset->y) * scale * graphene_vec2_get_y (&tangent);
res->y += (pt->y + offset->y) * scale * graphene_vec2_get_x (&tangent);
}
}
static gboolean
gtk_path_transform_op (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer data)
{
GtkPathTransform *transform = data;
switch (op)
{
case GSK_PATH_MOVE:
{
graphene_point_t res;
gtk_path_transform_point (transform->measure, &pts[0], &transform->offset, transform->scale, &res);
gsk_path_builder_move_to (transform->builder, res.x, res.y);
}
break;
case GSK_PATH_LINE:
{
graphene_point_t res;
gtk_path_transform_point (transform->measure, &pts[1], &transform->offset, transform->scale, &res);
gsk_path_builder_line_to (transform->builder, res.x, res.y);
}
break;
case GSK_PATH_QUAD:
{
graphene_point_t res[2];
gtk_path_transform_point (transform->measure, &pts[1], &transform->offset, transform->scale, &res[0]);
gtk_path_transform_point (transform->measure, &pts[2], &transform->offset, transform->scale, &res[1]);
gsk_path_builder_quad_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y);
}
break;
case GSK_PATH_CUBIC:
{
graphene_point_t res[3];
gtk_path_transform_point (transform->measure, &pts[1], &transform->offset, transform->scale, &res[0]);
gtk_path_transform_point (transform->measure, &pts[2], &transform->offset, transform->scale, &res[1]);
gtk_path_transform_point (transform->measure, &pts[3], &transform->offset, transform->scale, &res[2]);
gsk_path_builder_cubic_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y, res[2].x, res[2].y);
}
break;
case GSK_PATH_CONIC:
{
graphene_point_t res[2];
gtk_path_transform_point (transform->measure, &pts[1], &transform->offset, transform->scale, &res[0]);
gtk_path_transform_point (transform->measure, &pts[3], &transform->offset, transform->scale, &res[1]);
gsk_path_builder_conic_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y, weight);
}
break;
case GSK_PATH_CLOSE:
gsk_path_builder_close (transform->builder);
break;
default:
g_assert_not_reached();
return FALSE;
}
return TRUE;
}
static GskPath *
gtk_path_transform (GskPath *line_path,
GskPath *path,
const graphene_point_t *offset)
{
GskPathMeasure *measure = gsk_path_measure_new (line_path);
GtkPathTransform transform = { measure, gsk_path_builder_new (), *offset };
graphene_rect_t bounds;
gsk_path_get_bounds (path, &bounds);
if (bounds.origin.x + bounds.size.width > 0)
transform.scale = gsk_path_measure_get_length (measure) / (bounds.origin.x + bounds.size.width);
else
transform.scale = 1.0f;
gsk_path_foreach (path, -1, gtk_path_transform_op, &transform);
gsk_path_measure_unref (measure);
return gsk_path_builder_free_to_path (transform.builder);
}
static void
gtk_path_widget_clear_text_path (GtkPathWidget *self)
{
g_clear_pointer (&self->text_path, gsk_path_unref);
}
static void
gtk_path_widget_clear_paths (GtkPathWidget *self)
{
gtk_path_widget_clear_text_path (self);
g_clear_pointer (&self->line_path, gsk_path_unref);
}
static void
gtk_path_widget_create_text_path (GtkPathWidget *self)
{
GskPath *path;
graphene_point_t offset;
gtk_path_widget_clear_text_path (self);
path = create_path_from_text (GTK_WIDGET (self), self->text, &offset);
self->text_path = gtk_path_transform (self->line_path, path, &offset);
gsk_path_unref (path);
}
static void
gtk_path_widget_create_paths (GtkPathWidget *self)
{
double width = gtk_widget_get_width (GTK_WIDGET (self));
double height = gtk_widget_get_height (GTK_WIDGET (self));
GskPathBuilder *builder;
gtk_path_widget_clear_paths (self);
if (width <= 0 || height <= 0)
return;
builder = gsk_path_builder_new ();
gsk_path_builder_move_to (builder,
self->points[0].x * width, self->points[0].y * height);
gsk_path_builder_cubic_to (builder,
self->points[1].x * width, self->points[1].y * height,
self->points[2].x * width, self->points[2].y * height,
self->points[3].x * width, self->points[3].y * height);
self->line_path = gsk_path_builder_free_to_path (builder);
gtk_path_widget_create_text_path (self);
}
static void
gtk_path_widget_allocate (GtkWidget *widget,
int width,
int height,
int baseline)
{
GtkPathWidget *self = GTK_PATH_WIDGET (widget);
GTK_WIDGET_CLASS (gtk_path_widget_parent_class)->size_allocate (widget, width, height, baseline);
gtk_path_widget_create_paths (self);
}
static void
gtk_path_widget_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkPathWidget *self = GTK_PATH_WIDGET (widget);
double width = gtk_widget_get_width (widget);
double height = gtk_widget_get_height (widget);
GskPath *path;
GskStroke *stroke;
gsize i;
/* frosted glass the background */
gtk_snapshot_push_blur (snapshot, 100);
gdk_paintable_snapshot (self->background, snapshot, width, height);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 1, 1, 1, 0.6 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
/* draw the text */
if (self->text_path)
{
gtk_snapshot_push_fill (snapshot, self->text_path, GSK_FILL_RULE_WINDING);
gdk_paintable_snapshot (self->background, snapshot, width, height);
/* ... with an emboss effect */
stroke = gsk_stroke_new (2.0);
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT(1, 1));
gtk_snapshot_push_stroke (snapshot, self->text_path, stroke);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 0.2 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gsk_stroke_free (stroke);
gtk_snapshot_pop (snapshot);
gtk_snapshot_pop (snapshot);
}
if (self->editable && self->line_path)
{
GskPathBuilder *builder;
/* draw the control line */
stroke = gsk_stroke_new (1.0);
gtk_snapshot_push_stroke (snapshot, self->line_path, stroke);
gsk_stroke_free (stroke);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
/* draw the points */
builder = gsk_path_builder_new ();
for (i = 0; i < 4; i++)
{
gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (self->points[i].x * width, self->points[i].y * height), POINT_SIZE);
}
path = gsk_path_builder_free_to_path (builder);
gtk_snapshot_push_fill (snapshot, path, GSK_FILL_RULE_WINDING);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 1, 1, 1, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
stroke = gsk_stroke_new (1.0);
gtk_snapshot_push_stroke (snapshot, path, stroke);
gsk_stroke_free (stroke);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
gsk_path_unref (path);
}
}
static void
gtk_path_widget_set_text (GtkPathWidget *self,
const char *text)
{
if (g_strcmp0 (self->text, text) == 0)
return;
g_free (self->text);
self->text = g_strdup (text);
gtk_path_widget_create_paths (self);
gtk_widget_queue_draw (GTK_WIDGET (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TEXT]);
}
static void
gtk_path_widget_set_editable (GtkPathWidget *self,
gboolean editable)
{
if (self->editable == editable)
return;
self->editable = editable;
gtk_widget_queue_draw (GTK_WIDGET (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_EDITABLE]);
}
static void
gtk_path_widget_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkPathWidget *self = GTK_PATH_WIDGET (object);
switch (prop_id)
{
case PROP_TEXT:
gtk_path_widget_set_text (self, g_value_get_string (value));
break;
case PROP_EDITABLE:
gtk_path_widget_set_editable (self, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_path_widget_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkPathWidget *self = GTK_PATH_WIDGET (object);
switch (prop_id)
{
case PROP_TEXT:
g_value_set_string (value, self->text);
break;
case PROP_EDITABLE:
g_value_set_boolean (value, self->editable);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_path_widget_dispose (GObject *object)
{
GtkPathWidget *self = GTK_PATH_WIDGET (object);
gtk_path_widget_clear_paths (self);
G_OBJECT_CLASS (gtk_path_widget_parent_class)->dispose (object);
}
static void
gtk_path_widget_class_init (GtkPathWidgetClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gtk_path_widget_dispose;
object_class->set_property = gtk_path_widget_set_property;
object_class->get_property = gtk_path_widget_get_property;
widget_class->size_allocate = gtk_path_widget_allocate;
widget_class->snapshot = gtk_path_widget_snapshot;
properties[PROP_TEXT] =
g_param_spec_string ("text",
"text",
"Text transformed along a path",
NULL,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
properties[PROP_EDITABLE] =
g_param_spec_boolean ("editable",
"editable",
"If the path can be edited by the user",
FALSE,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPS, properties);
}
static void
drag_begin (GtkGestureDrag *gesture,
double x,
double y,
GtkPathWidget *self)
{
graphene_point_t mouse = GRAPHENE_POINT_INIT (x, y);
double width = gtk_widget_get_width (GTK_WIDGET (self));
double height = gtk_widget_get_height (GTK_WIDGET (self));
gsize i;
for (i = 0; i < 4; i++)
{
if (graphene_point_distance (&GRAPHENE_POINT_INIT (self->points[i].x * width, self->points[i].y * height), &mouse, NULL, NULL) <= POINT_SIZE)
{
self->active_point = i;
break;
}
}
if (i == 4)
{
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
return;
}
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
drag_update (GtkGestureDrag *drag,
double offset_x,
double offset_y,
GtkPathWidget *self)
{
double width = gtk_widget_get_width (GTK_WIDGET (self));
double height = gtk_widget_get_height (GTK_WIDGET (self));
double start_x, start_y;
gtk_gesture_drag_get_start_point (drag, &start_x, &start_y);
self->points[self->active_point] = GRAPHENE_POINT_INIT ((start_x + offset_x) / width,
(start_y + offset_y) / height);
self->points[self->active_point].x = CLAMP (self->points[self->active_point].x, 0, 1);
self->points[self->active_point].y = CLAMP (self->points[self->active_point].y, 0, 1);
gtk_path_widget_create_paths (self);
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
pointer_motion (GtkEventControllerMotion *controller,
double x,
double y,
GtkPathWidget *self)
{
GskPathPoint point;
graphene_point_t pos;
if (gsk_path_get_closest_point (self->line_path,
&GRAPHENE_POINT_INIT (x, y),
INFINITY,
&point))
{
gsk_path_point_get_position (&point, self->line_path, &pos);
gtk_widget_queue_draw (GTK_WIDGET (self));
}
}
static void
pointer_leave (GtkEventControllerMotion *controller,
GtkPathWidget *self)
{
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
gtk_path_widget_init (GtkPathWidget *self)
{
GtkEventController *controller;
controller = GTK_EVENT_CONTROLLER (gtk_gesture_drag_new ());
g_signal_connect (controller, "drag-begin", G_CALLBACK (drag_begin), self);
g_signal_connect (controller, "drag-update", G_CALLBACK (drag_update), self);
g_signal_connect (controller, "drag-end", G_CALLBACK (drag_update), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
controller = GTK_EVENT_CONTROLLER (gtk_event_controller_motion_new ());
g_signal_connect (controller, "enter", G_CALLBACK (pointer_motion), self);
g_signal_connect (controller, "motion", G_CALLBACK (pointer_motion), self);
g_signal_connect (controller, "leave", G_CALLBACK (pointer_leave), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
self->points[0] = GRAPHENE_POINT_INIT (0.1, 0.9);
self->points[1] = GRAPHENE_POINT_INIT (0.3, 0.1);
self->points[2] = GRAPHENE_POINT_INIT (0.7, 0.1);
self->points[3] = GRAPHENE_POINT_INIT (0.9, 0.9);
self->background = GDK_PAINTABLE (gdk_texture_new_from_resource ("/sliding_puzzle/portland-rose.jpg"));
gtk_path_widget_set_text (self, "It's almost working");
}
GtkWidget *
gtk_path_widget_new (void)
{
GtkPathWidget *self;
self = g_object_new (GTK_TYPE_PATH_WIDGET, NULL);
return GTK_WIDGET (self);
}
GtkWidget *
do_path_text (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkBuilder *builder;
g_type_ensure (GTK_TYPE_PATH_WIDGET);
builder = gtk_builder_new_from_resource ("/path_text/path_text.ui");
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
g_object_unref (builder);
}
if (!gtk_widget_get_visible (window))
gtk_window_present (GTK_WINDOW (window));
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}
+38
View File
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window">
<property name="title" translatable="yes">Text along a Path</property>
<child type="titlebar">
<object class="GtkHeaderBar">
<child type="end">
<object class="GtkToggleButton" id="edit-toggle">
<property name="icon-name">document-edit-symbolic</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkRevealer">
<property name="reveal-child" bind-source="edit-toggle" bind-property="active" bind-flags="sync-create"></property>
<child>
<object class="GtkEntry" id="text">
<property name="text">Through the looking glass</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkPathWidget" id="view">
<property name="editable" bind-source="edit-toggle" bind-property="active" bind-flags="sync-create"></property>
<property name="text" bind-source="text" bind-property="text" bind-flags="sync-create"></property>
<property name="hexpand">true</property>
<property name="vexpand">true</property>
</object>
</child>
</object>
</child>
</object>
</interface>
+150 -2
View File
@@ -1,6 +1,6 @@
/* Path/Map
/* Path/Walk
*
* This demo shows how to draw a map using paths.
* This demo draws a world map and shows how to animate objects along a GskPath.
*
* The world map that is used here is a path with 211 lines and 1569 cubic
* Bėzier segments in 121 contours.
@@ -16,6 +16,7 @@ G_DECLARE_FINAL_TYPE (GtkPathWalk, gtk_path_walk, GTK, PATH_WALK, GtkWidget)
enum {
PROP_0,
PROP_N_POINTS,
PROP_PATH,
N_PROPS
};
@@ -25,7 +26,10 @@ struct _GtkPathWalk
GtkWidget parent_instance;
GskPath *path;
GskPathMeasure *measure;
graphene_rect_t bounds;
GskPath *arrow_path;
guint n_points;
};
struct _GtkPathWalkClass
@@ -37,6 +41,74 @@ static GParamSpec *properties[N_PROPS] = { NULL, };
G_DEFINE_TYPE (GtkPathWalk, gtk_path_walk, GTK_TYPE_WIDGET)
static void
rgba_init_from_hsla (GdkRGBA *rgba,
float hue,
float saturation,
float lightness,
float alpha)
{
float m1, m2;
if (lightness <= 0.5)
m2 = lightness * (1 + saturation);
else
m2 = lightness + saturation - lightness * saturation;
m1 = 2 * lightness - m2;
rgba->alpha = alpha;
if (saturation == 0)
{
rgba->red = lightness;
rgba->green = lightness;
rgba->blue = lightness;
}
else
{
hue = hue + 120;
while (hue > 360)
hue -= 360;
while (hue < 0)
hue += 360;
if (hue < 60)
rgba->red = m1 + (m2 - m1) * hue / 60;
else if (hue < 180)
rgba->red = m2;
else if (hue < 240)
rgba->red = m1 + (m2 - m1) * (240 - hue) / 60;
else
rgba->red = m1;
hue -= 120;
if (hue < 0)
hue += 360;
if (hue < 60)
rgba->green = m1 + (m2 - m1) * hue / 60;
else if (hue < 180)
rgba->green = m2;
else if (hue < 240)
rgba->green = m1 + (m2 - m1) * (240 - hue) / 60;
else
rgba->green = m1;
hue -= 120;
if (hue < 0)
hue += 360;
if (hue < 60)
rgba->blue = m1 + (m2 - m1) * hue / 60;
else if (hue < 180)
rgba->blue = m2;
else if (hue < 240)
rgba->blue = m1 + (m2 - m1) * (240 - hue) / 60;
else
rgba->blue = m1;
}
}
static void
gtk_path_walk_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
@@ -44,7 +116,9 @@ gtk_path_walk_snapshot (GtkWidget *widget,
GtkPathWalk *self = GTK_PATH_WALK (widget);
double width = gtk_widget_get_width (widget);
double height = gtk_widget_get_height (widget);
float length, progress;
GskStroke *stroke;
guint i;
if (self->path == NULL)
return;
@@ -57,6 +131,35 @@ gtk_path_walk_snapshot (GtkWidget *widget,
gtk_snapshot_pop (snapshot);
gsk_stroke_free (stroke);
length = gsk_path_measure_get_length (self->measure);
progress = 25.f * gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget)) / G_USEC_PER_SEC;
stroke = gsk_stroke_new (1.0);
for (i = 0; i < self->n_points; i++)
{
GskPathPoint point;
graphene_point_t position;
float angle;
GdkRGBA color;
float distance;
distance = i * length / self->n_points;
distance = fmod (distance + progress, length);
gsk_path_measure_get_point (self->measure, distance, &point);
gsk_path_point_get_position (&point, self->path, &position);
angle = gsk_path_point_get_rotation (&point, self->path, GSK_PATH_FROM_START);
rgba_init_from_hsla (&color, 360.f * i / self->n_points, 1, 0.5, 1);
gtk_snapshot_save (snapshot);
gtk_snapshot_translate (snapshot, &position);
gtk_snapshot_rotate (snapshot, angle);
gtk_snapshot_append_fill (snapshot, self->arrow_path, GSK_FILL_RULE_EVEN_ODD, &color);
gtk_snapshot_append_stroke (snapshot, self->arrow_path, stroke, &(GdkRGBA) { 0, 0, 0, 1 });
gtk_snapshot_restore (snapshot);
}
gsk_stroke_free (stroke);
gtk_snapshot_restore (snapshot);
}
@@ -77,6 +180,20 @@ gtk_path_walk_measure (GtkWidget *widget,
*minimum = *natural = (int) ceilf (self->bounds.size.height);
}
static void
gtk_path_walk_set_n_points (GtkPathWalk *self,
gsize n_points)
{
if (self->n_points == n_points)
return;
self->n_points = n_points;
gtk_widget_queue_draw (GTK_WIDGET (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_POINTS]);
}
static void
gtk_path_walk_set_path (GtkPathWalk *self,
GskPath *path)
@@ -94,6 +211,7 @@ gtk_path_walk_set_path (GtkPathWalk *self,
stroke = gsk_stroke_new (2.0);
gsk_path_get_stroke_bounds (path, stroke, &self->bounds);
gsk_stroke_free (stroke);
self->measure = gsk_path_measure_new (self->path);
}
gtk_widget_queue_resize (GTK_WIDGET (self));
@@ -112,6 +230,10 @@ gtk_path_walk_set_property (GObject *object,
switch (prop_id)
{
case PROP_N_POINTS:
gtk_path_walk_set_n_points (self, g_value_get_uint (value));
break;
case PROP_PATH:
gtk_path_walk_set_path (self, g_value_get_boxed (value));
break;
@@ -132,6 +254,10 @@ gtk_path_walk_get_property (GObject *object,
switch (prop_id)
{
case PROP_N_POINTS:
g_value_set_uint (value, self->n_points);
break;
case PROP_PATH:
g_value_set_boxed (value, self->path);
break;
@@ -148,6 +274,8 @@ gtk_path_walk_dispose (GObject *object)
GtkPathWalk *self = GTK_PATH_WALK (object);
g_clear_pointer (&self->path, gsk_path_unref);
g_clear_pointer (&self->measure, gsk_path_measure_unref);
g_clear_pointer (&self->arrow_path, gsk_path_unref);
G_OBJECT_CLASS (gtk_path_walk_parent_class)->dispose (object);
}
@@ -165,6 +293,13 @@ gtk_path_walk_class_init (GtkPathWalkClass *klass)
widget_class->snapshot = gtk_path_walk_snapshot;
widget_class->measure = gtk_path_walk_measure;
properties[PROP_N_POINTS] =
g_param_spec_uint ("n-points",
NULL, NULL,
1, G_MAXUINT,
500,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
properties[PROP_PATH] =
g_param_spec_boxed ("path",
NULL, NULL,
@@ -174,6 +309,16 @@ gtk_path_walk_class_init (GtkPathWalkClass *klass)
g_object_class_install_properties (object_class, N_PROPS, properties);
}
static gboolean
tick_tick_tick (GtkWidget *self,
GdkFrameClock *frame_clock,
gpointer unused)
{
gtk_widget_queue_draw (GTK_WIDGET (self));
return G_SOURCE_CONTINUE;
}
static void
gtk_path_walk_init (GtkPathWalk *self)
{
@@ -185,6 +330,9 @@ gtk_path_walk_init (GtkPathWalk *self)
g_bytes_unref (data);
gtk_path_walk_set_path (self, path);
gsk_path_unref (path);
self->arrow_path = gsk_path_parse ("M 5 0 L 0 -5. 0 -2, -5 -2, -5 2, 0 2, 0 5 Z");
self->n_points = 500;
gtk_widget_add_tick_callback (GTK_WIDGET (self), tick_tick_tick, NULL, NULL);
}
GtkWidget *
+18 -2
View File
@@ -2,16 +2,32 @@
<interface>
<object class="GtkWindow" id="window">
<property name="title" translatable="yes">World Map</property>
<child>
<property name="titlebar">
<object class="GtkHeaderBar">
<child type="end">
<object class="GtkSpinButton">
<property name="adjustment">
<object class="GtkAdjustment" id="adjustment">
<property name="lower">0</property>
<property name="upper">5000</property>
<property name="value">500</property>
</object>
</property>
</object>
</child>
</object>
</property>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkPathWalk" id="view">
<property name="n-points" bind-source="adjustment" bind-property="value"/>
<property name="hexpand">true</property>
<property name="vexpand">true</property>
</object>
</child>
</object>
</child>
</property>
</object>
</interface>
+29
View File
@@ -147,6 +147,18 @@ Creates a node like `gsk_cross_fade_node_new()` with the given properties.
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 |
Creates a node like `gsk_fill_node_new()` with the given properties.
The default child node is created with the bounds of the path.
### glshader
| property | syntax | default | printed |
@@ -289,6 +301,23 @@ Creates a node like `gsk_rounded_clip_node_new()` with the given properties.
Creates a node like `gsk_shadow_node_new()` with the given properties.
### stroke
| property | syntax | default | printed |
| ----------- | ------------------ | ----------------- | ----------- |
| child | `<node>` | *see below* | always |
| path | `<string>` | "" | always |
| line-width | `<number>` | 0 | non-default |
| line-cap | `<line-cap>` | butt | always |
| line-join | `<line-join>` | miter | always |
| miter-limit | `<number>` | 4 | non-default |
| dash | `<number>{+}|none` | none | non-default |
| dash-offset | `<number>` | 0 | non-default |
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.
### text
| property | syntax | default | printed |
+15 -2
View File
@@ -32,21 +32,34 @@ show_class_hierarchy = true
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/"
[extra]
content_files = [
"paths.md",
]
content_images = [
"gtk-logo.svg",
"images/arc-dark.png",
"images/arc-light.png",
"images/caps-dark.png",
"images/caps-light.png",
"images/conic-light.png",
"images/conic-dark.png",
"images/cubic-dark.png",
"images/cubic-light.png",
"images/curvature-dark.png",
"images/curvature-light.png",
"images/directions-dark.png",
"images/directions-light.png",
"images/fill-even-odd.png",
"images/fill-winding.png",
"images/join-dark.png",
"images/join-light.png",
"images/line-dark.png",
"images/line-light.png",
"images/quad-dark.png",
"images/quad-light.png",
"images/path-dark.png",
"images/path-light.png",
"images/quad-dark.png",
"images/quad-light.png",
"images/stroke-miter.png",
"images/stroke-round.png",
]
urlmap_file = "urlmap.js"
Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

+92
View File
@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="arcto.svg"
inkscape:export-filename="cubic-light.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="0.75989759"
inkscape:cx="399.39592"
inkscape:cy="466.51023"
inkscape:window-width="1920"
inkscape:window-height="1123"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
showgrid="false" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
d="M 58.033485,123.96862 C 75.231194,113.95411 92.489919,103.26728 107.81401,113.89786"
id="path3"
sodipodi:nodetypes="cc" />
<ellipse
style="fill:none;stroke:#000000;stroke-width:0.20061772;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2"
cx="-16.837238"
cy="154.55043"
rx="35.832706"
ry="17.920988"
transform="matrix(0.86643544,-0.49928912,0.59215321,0.8058254,0,0)" />
<path
style="fill:none;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
d="M 57.432798,124.38759 86.59638,102.1496 107.25717,113.71009"
id="path1"
sodipodi:nodetypes="ccc" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-9"
cx="86.580566"
cy="102.81618"
r="1.5" />
<path
style="fill:#f90048;stroke:#a2a2a2;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 45.061871,134.70541 12.60825,-10.20893"
id="path4-4"
sodipodi:nodetypes="cc" />
<path
style="fill:#f90048;stroke:#a2a2a2;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:1, 3;stroke-dashoffset:0;stroke-opacity:1"
d="m 35.405008,142.35717 8.95641,-7.26298"
id="path4-8-8"
sodipodi:nodetypes="cc" />
<circle
style="fill:#818181;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-61-1"
cx="57.597607"
cy="124.23325"
r="1.5" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-6-5"
cx="108.01463"
cy="114.17829"
r="1.5" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

+93
View File
@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="conic.svg"
inkscape:export-filename="path-dark.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="1.5197952"
inkscape:cx="397.75096"
inkscape:cy="525.39974"
inkscape:window-width="1920"
inkscape:window-height="1123"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
showgrid="false" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;stroke:#8b8b8b;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 66.52304,196.79607 c 27.88945,-10.42358 28.400227,-11.25919 57.24918,-4.59693"
id="path5-7-6"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#848484;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 66.150275,196.9925 c 28.059619,-18.89157 28.355331,-21.42218 57.249175,-4.59693"
id="path5"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 65.439496,197.17632 30.328009,-21.33704 28.506125,16.61621"
id="path6" />
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 66.25585,197.17683 c 29.459015,-15.97487 29.941733,-16.52508 57.24918,-4.59693"
id="path5-7"
sodipodi:nodetypes="cc" />
<path
style="fill:#f90048;stroke:#a2a2a2;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 52.936092,207.66575 12.60825,-10.20893"
id="path4"
sodipodi:nodetypes="cc" />
<path
style="fill:#f90048;stroke:#a2a2a2;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:1, 3;stroke-dashoffset:0;stroke-opacity:1"
d="m 43.279229,215.31751 8.95641,-7.26298"
id="path4-8"
sodipodi:nodetypes="cc" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7"
cx="95.69075"
cy="175.70657"
r="1.5" />
<circle
style="fill:#818181;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-61"
cx="65.471832"
cy="197.19359"
r="1.5" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-6"
cx="123.73506"
cy="192.49165"
r="1.5" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

+65
View File
@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="curvature.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="1.0746575"
inkscape:cx="396.87064"
inkscape:cy="561.57428"
inkscape:window-width="1920"
inkscape:window-height="1123"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
d="m 61.499887,117.85302 0.05055,-14.89554"
id="path3"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
d="m 47.704374,176.11887 c 0,0 -17.048386,-67.06278 9.674156,-72.76426 29.478854,-6.289566 30.433539,55.72526 58.46942,50.81836"
id="path1"
sodipodi:nodetypes="csc" />
<ellipse
style="fill:none;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2"
cy="117.87344"
cx="61.445835"
rx="14.692688"
ry="14.525347" />
<circle
style="fill:#818181;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path2-8-9"
cx="61.42588"
cy="117.79034"
r="1.5" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

+5 -1
View File
@@ -1,3 +1,7 @@
gsk_expand_content_md_files = [
'paths.md',
]
if get_option('documentation')
gsk4_toml = configure_file(
input: 'gsk4.toml.in',
@@ -21,7 +25,7 @@ if get_option('documentation')
'@INPUT1@',
],
depends: [ gdk_gir[0] ],
depend_files: [ expand_content_md_files ],
depend_files: [ gsk_expand_content_md_files ],
build_by_default: true,
install: true,
install_dir: docs_dir,
+174
View File
@@ -0,0 +1,174 @@
Title: Paths
Slug: paths
GSK provides a path API that can be used to render more complex
shapes than lines or rounded rectangles. It is comparable to cairos
[path API](https://www.cairographics.org/manual/cairo-Paths.html),
with some notable differences.
In general, a path consists of one or more connected **_contours_**,
each of which may have multiple **_operations_**, and may or may not be closed.
Operations can be straight lines or curves of various kinds. At the points
where the operations connect, the path can have sharp turns.
<figure>
<picture>
<source srcset="path-dark.png" media="(prefers-color-scheme: dark)">
<img alt="A path with multiple contours" src="path-light.png">
</picture>
<figcaption>A path with one closed, and one open contour</figcaption>
</figure>
The central object of the GSK path API is the immutable [struct@Gsk.Path]
struct, which contains path data in compact form suitable for rendering.
## Creating Paths
Since `GskPath` is immutable, the auxiliary [struct@Gsk.PathBuilder] struct
can be used to construct a path piece by piece. The pieces are specified with
points, some of which will be on the path, while others are just **_control points_**
that are used to influence the shape of the resulting path.
<figure>
<picture>
<source srcset="cubic-dark.png" media="(prefers-color-scheme: dark)">
<img alt="An cubic Bézier" src="cubic-light.png">
</picture>
<figcaption>A cubic Bézier operation, with 2 control points</figcaption>
</figure>
The `GskPathBuilder` API has three distinct groups of functions:
- Functions for building contours from individual operations, like [method@Gsk.PathBuilder.move_to],
[method@Gsk.PathBuilder.line_to], [method@Gsk.PathBuilder.cubic_to], [method@Gsk.PathBuilder.close]. `GskPathBuilder` maintains a **_current point_**, so these methods all
take one less points than necessary for the operation (e.g. `gsk_path_builder_line_to`
only takes a single point and draws a line from the current point to the new point).
- Functions for adding complete contours, such as [method@Gsk.PathBuilder.add_rect],
[method@Gsk.PathBuilder.add_rounded_rect], [method@Gsk.PathBuilder.add_circle].
- Adding parts of a preexisting path. Functions in this group include
[method@Gsk.PathBuilder.add_path] and [method@Gsk.PathBuilder.add_segment].
When you are done with building a path, you can convert the accumulated path
data into a `GskPath` struct with [method@Gsk.PathBuilder.free_to_path].
A sometimes convenient alternative is to create a path from a serialized form,
with [func@Gsk.Path.parse]. This function interprets strings in SVG path syntax,
such as:
M 100 100 C 100 200 200 200 200 100 Z
## Rendering with Paths
There are two main ways to render with paths. The first is to **_fill_** the
interior of a path with a color or more complex content, such as a gradient.
GSK supports different ways of determining what part of the plane are interior
to the path, which can be selected with a [enum@Gsk.FillRule] value.
<figure>
<picture>
<img alt="A filled path" src="fill-winding.png">
</picture>
<figcaption>A path filled with GSK_FILL_RULE_WINDING</figcaption>
</figure>
<figure>
<picture>
<img alt="A filled path" src="fill-even-odd.png">
</picture>
<figcaption>The same path, filled with GSK_FILL_RULE_EVEN_ODD</figcaption>
</figure>
To fill a path, use [gtk_snapshot_append_fill()](../gtk4/method.Snapshot.append_fill.html)
or the more general [gtk_snapshot_push_fill()](../gtk4/method.Snapshot.push_fill.html).
Alternatively, a path can be **_stroked_**, which means to emulate drawing
with an idealized pen along the path. The result of stroking a path is another
path (the **_stroke path_**), which is then filled.
The stroke operation can be influenced with the [struct@Gsk.Stroke] struct
that collects various stroke parameters, such as the line width, the style
of line joins and line caps, and a dash pattern.
<figure>
<picture>
<img alt="A stroked path" src="stroke-miter.png">
</picture>
<figcaption>The same path, stroked with GSK_LINE_JOIN_MITER</figcaption>
</figure>
<figure>
<picture>
<img alt="A stroked path" src="stroke-round.png">
</picture>
<figcaption>The same path, stroked with GSK_LINE_JOIN_ROUND</figcaption>
</figure>
To stroke a path, use
[gtk_snapshot_append_stroke()](../gtk4/method.Snapshot.append_stroke.html)
or [gtk_snapshot_push_stroke()](../gtk4/method.Snapshot.push_stroke.html).
## Hit testing
When paths are rendered as part of an interactive interface, it is sometimes
necessary to determine whether the mouse points is over the path. GSK provides
[method@Gsk.Path.in_fill] for this purpose.
## Path length
An important property of paths is their **_length_**. Computing it efficiently
requires caching, therefore GSK provides a separate [struct@Gsk.PathMeasure] object
to deal with path lengths. After constructing a `GskPathMeasure` object for a path,
it can be used to determine the length of the path with [method@Gsk.PathMeasure.get_length]
and locate points at a given distance into the path with [method@Gsk.PathMeasure.get_point].
## Other Path APIs
Paths have uses beyond rendering, for example as trajectories in animations.
In such uses, it is often important to access properties of paths, such as
their tangents at certain points. GSK provides an abstract representation
for points on a path in the form of the [struct@Gsk.PathPoint] struct.
You can query properties of a path at certain point once you have a
`GskPathPoint` representing that point.
`GskPathPoint` structs can be compared for equality with [method@Gsk.PathPoint.equal]
and ordered wrt. to which one comes first, using [method@Gsk.PathPoint.compare].
To obtain a `GskPathPoint`, use [method@Gsk.Path.get_closest_point],
[method@Gsk.Path.get_start_point], [method@Gsk.Path.get_end_point] or
[method@Gsk.PathMeasure.get_point].
To query properties of the path at a point, use [method@Gsk.PathPoint.get_position],
[method@Gsk.PathPoint.get_tangent], [method@Gsk.PathPoint.get_rotation],
[method@Gsk.PathPoint.get_curvature] and [method@Gsk.PathPoint.get_distance].
Some of the properties can have different values for the path going into
the point and the path leaving the point, typically at points where the
path takes sharp turns. Examples for this are tangents (which can have up
to 4 different values) and curvatures (which can have two different values).
<figure>
<picture>
<source srcset="directions-dark.png" media="(prefers-color-scheme: dark)">
<img alt="Path Tangents" src="directions-light.png">
</picture>
<figcaption>Path Tangents</figcaption>
</figure>
## Going beyond GskPath
Lots of powerful functionality can be implemented for paths:
- Finding intersections
- Offsetting curves
- Turning stroke outlines into paths
- Molding curves (making them pass through a given point)
GSK does not provide API for all of these, but it does offer a way to get at
the underlying Bézier curves, so you can implement such functionality yourself.
You can use [method@Gsk.Path.foreach] to iterate over the operations of the
path, and get the points needed to reconstruct or modify the path piece by piece.
See e.g. the [Primer on Bézier curves](https://pomax.github.io/bezierinfo/)
for inspiration of useful things to explore.
+12
View File
@@ -44,6 +44,10 @@ segments.
Allow cubic Bézier curves to be used in the generated path.
``--allow-conic``
Allow conic Bézier curves to be used in the generated path.
Showing
^^^^^^^
@@ -65,6 +69,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``
Fill the path (this is the default).
``--stroke``
Stroke the path instead of filling it.
@@ -130,6 +138,10 @@ The interior of the path is filled.
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.
+7 -1
View File
@@ -95,10 +95,11 @@ static gboolean
gdk_gl_texture_invoke_callback (gpointer data)
{
InvokeData *invoke = data;
GdkGLContext *context;
GdkGLContext *context, *previous;
context = gdk_display_get_gl_context (gdk_gl_context_get_display (invoke->self->context));
previous = gdk_gl_context_get_current ();
gdk_gl_context_make_current (context);
if (invoke->self->sync && context != invoke->self->context)
@@ -110,6 +111,11 @@ gdk_gl_texture_invoke_callback (gpointer data)
g_atomic_int_set (&invoke->spinlock, 1);
if (previous)
gdk_gl_context_make_current (previous);
else
gdk_gl_context_clear_current ();
return FALSE;
}
+16 -2
View File
@@ -25,10 +25,12 @@
#include "gdkprivate.h"
/* HACK: So we don't need to include any (not-yet-created) GSK or GTK headers */
GdkSnapshot * gtk_snapshot_new (void);
void gtk_snapshot_push_debug (GdkSnapshot *snapshot,
const char *message,
...) G_GNUC_PRINTF (2, 3);
void gtk_snapshot_pop (GdkSnapshot *snapshot);
GdkPaintable * gtk_snapshot_free_to_paintable (GdkSnapshot *snapshot);
/**
* GdkPaintable:
@@ -102,9 +104,21 @@ gdk_paintable_default_snapshot (GdkPaintable *paintable,
static GdkPaintable *
gdk_paintable_default_get_current_image (GdkPaintable *paintable)
{
g_warning ("FIXME: implement by snapshotting at default size and returning a GskRendererNodePaintable");
int width, height;
GdkSnapshot *snapshot;
return paintable;
/* No need to check whether the paintable is static, as
* gdk_paintable_get_current_image () takes care of that already. */
width = gdk_paintable_get_intrinsic_width (paintable);
height = gdk_paintable_get_intrinsic_height (paintable);
if (width <= 0 || height <= 0)
return gdk_paintable_new_empty (width, height);
snapshot = gtk_snapshot_new ();
gdk_paintable_snapshot (paintable, snapshot, width, height);
return gtk_snapshot_free_to_paintable (snapshot);
}
static GdkPaintableFlags
+1 -1
View File
@@ -331,7 +331,7 @@ _gdk_macos_monitor_reconfigure (GdkMacosMonitor *self)
gdk_monitor_set_physical_size (GDK_MONITOR (self), width_mm, height_mm);
gdk_monitor_set_scale_factor (GDK_MONITOR (self), scale_factor);
gdk_monitor_set_refresh_rate (GDK_MONITOR (self), refresh_rate);
gdk_monitor_set_subpixel_layout (GDK_MONITOR (self), GDK_SUBPIXEL_LAYOUT_UNKNOWN);
gdk_monitor_set_subpixel_layout (GDK_MONITOR (self), subpixel_layout);
self->workarea = [screen visibleFrame];
+2 -1
View File
@@ -93,7 +93,8 @@ gdk_wayland_app_launch_context_get_startup_notify_id (GAppLaunchContext *context
id = app_launch_data.token;
wl_event_queue_destroy (event_queue);
}
else if (gtk_shell1_get_version (display->gtk_shell) >= GTK_SHELL1_NOTIFY_LAUNCH_SINCE_VERSION)
else if (display->gtk_shell &&
gtk_shell1_get_version (display->gtk_shell) >= GTK_SHELL1_NOTIFY_LAUNCH_SINCE_VERSION)
{
id = g_uuid_string_random ();
gtk_shell1_notify_launch (display->gtk_shell, id);
+3 -1
View File
@@ -201,7 +201,7 @@ gdk_x11_clipboard_formats_to_targets (GdkContentFormats *formats)
continue;
if (g_str_equal (mime_types[i], special_targets[j].mime_type))
targets = g_slist_prepend (targets, (gpointer) g_intern_string (special_targets[j].x_target));
targets = g_slist_prepend (targets, (gpointer) g_intern_static_string (special_targets[j].x_target));
}
targets = g_slist_prepend (targets, (gpointer) mime_types[i]);
}
@@ -238,6 +238,8 @@ gdk_x11_clipboard_formats_to_atoms (GdkDisplay *display,
for (l = targets; l; l = l->next)
atoms[i++] = gdk_x11_get_xatom_by_name_for_display (display, l->data);
g_slist_free (targets);
return atoms;
}
+1
View File
@@ -22,6 +22,7 @@
#include <gsk/gskenums.h>
#include <gsk/gskpath.h>
#include <gsk/gskpathbuilder.h>
#include <gsk/gskpathmeasure.h>
#include <gsk/gskpathpoint.h>
#include <gsk/gskrenderer.h>
#include <gsk/gskrendernode.h>
+330 -5
View File
@@ -76,12 +76,25 @@ struct _GskContourClass
graphene_vec2_t *tangent);
float (* get_curvature) (const GskContour *contour,
GskRealPathPoint *point,
GskPathDirection direction,
graphene_point_t *center);
void (* add_segment) (const GskContour *contour,
GskPathBuilder *builder,
gboolean emit_move_to,
GskRealPathPoint *start,
GskRealPathPoint *end);
gpointer (* init_measure) (const GskContour *contour,
float tolerance,
float *out_length);
void (* free_measure) (const GskContour *contour,
gpointer measure_data);
void (* get_point) (const GskContour *contour,
gpointer measure_data,
float distance,
GskRealPathPoint *result);
float (* get_distance) (const GskContour *contour,
GskRealPathPoint *point,
gpointer measure_data);
};
/* {{{ Utilities */
@@ -188,6 +201,7 @@ static gboolean
add_reverse (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer user_data)
{
GskPathBuilder *builder = user_data;
@@ -199,7 +213,7 @@ add_reverse (GskPathOperation op,
if (op == GSK_PATH_CLOSE)
op = GSK_PATH_LINE;
gsk_curve_init_foreach (&c, op, pts, n_pts);
gsk_curve_init_foreach (&c, op, pts, n_pts, weight);
gsk_curve_reverse (&c, &r);
gsk_curve_builder_to (&r, builder);
@@ -287,6 +301,15 @@ gsk_standard_contour_print (const GskContour *contour,
_g_string_append_point (string, &pt[3]);
break;
case GSK_PATH_CONIC:
g_string_append (string, " O ");
_g_string_append_point (string, &pt[1]);
g_string_append (string, ", ");
_g_string_append_point (string, &pt[3]);
g_string_append (string, ", ");
_g_string_append_double (string, pt[2].x);
break;
default:
g_assert_not_reached();
return;
@@ -319,7 +342,7 @@ gsk_standard_contour_get_stroke_bounds (const GskContour *contour,
if (self->n_points == 0)
return FALSE;
extra = MAX (stroke->line_width / 2, gsk_stroke_get_join_width (stroke) / 2);
extra = MAX (stroke->line_width, gsk_stroke_get_join_width (stroke));
gsk_bounding_box_init (bounds, &GRAPHENE_POINT_INIT (self->bounds.min.x - extra,
self->bounds.min.y - extra),
@@ -523,16 +546,35 @@ gsk_standard_contour_get_tangent (const GskContour *contour,
static float
gsk_standard_contour_get_curvature (const GskContour *contour,
GskRealPathPoint *point,
GskPathDirection direction,
graphene_point_t *center)
{
GskStandardContour *self = (GskStandardContour *) contour;
GskCurve curve;
gsize idx;
float t;
if (G_UNLIKELY (point->idx == 0))
return 0;
gsk_curve_init (&curve, self->ops[point->idx]);
return gsk_curve_get_curvature (&curve, point->t, center);
idx = point->idx;
t = point->t;
if (t == 0 && idx > 1 &&
(direction == GSK_PATH_FROM_START || direction == GSK_PATH_TO_START))
{
idx--;
t = 1;
}
else if (t == 1 && idx + 1 < self->n_ops &&
(direction == GSK_PATH_FROM_END || direction == GSK_PATH_TO_END))
{
idx++;
t = 0;
}
gsk_curve_init (&curve, self->ops[idx]);
return gsk_curve_get_curvature (&curve, t, center);
}
static void
@@ -602,6 +644,252 @@ gsk_standard_contour_add_segment (const GskContour *contour,
}
}
typedef struct
{
gsize idx;
float t;
float length;
} CurvePoint;
static void
add_measure (const GskCurve *curve,
float length,
float tolerance,
float t1,
float l1,
GArray *array)
{
GskCurve c;
float ll, l0;
float t0;
float tt, ll0;
CurvePoint *p = &g_array_index (array, CurvePoint, array->len - 1);
gsize idx = p->idx;
/* Check if we can add (t1, length + l1) without further
* splitting. We check two things:
* - Is the curve close to a straight line (length-wise) ?
* - Does the roundtrip length<>t not deviate too much ?
*/
if (curve->op == GSK_PATH_LINE ||
curve->op == GSK_PATH_CLOSE)
goto done;
t0 = (p->t + t1) / 2;
if (t0 == p->t || t0 == t1)
goto done;
gsk_curve_split (curve, t0, &c, NULL);
l0 = gsk_curve_get_length (&c);
ll = (p->length + length + l1) / 2;
tt = gsk_curve_at_length (curve, l0, 0.001);
gsk_curve_split (curve, tt, &c, NULL);
ll0 = gsk_curve_get_length (&c);
if (fabsf (length + l0 - ll) < tolerance &&
fabsf (ll0 - l0) < tolerance)
{
done:
g_array_append_val (array, ((CurvePoint){ idx, t1, length + l1 }));
}
else
{
add_measure (curve, length, tolerance, t0, l0, array);
add_measure (curve, length, tolerance, t1, l1, array);
}
}
static int
cmpfloat (const void *p1, const void *p2)
{
const float *f1 = p1;
const float *f2 = p2;
return *f1 < *f2 ? -1 : (*f1 > *f2 ? 1 : 0);
}
static gpointer
gsk_standard_contour_init_measure (const GskContour *contour,
float tolerance,
float *out_length)
{
const GskStandardContour *self = (const GskStandardContour *) contour;
GArray *array;
float length;
array = g_array_new (FALSE, FALSE, sizeof (CurvePoint));
length = 0;
for (gsize i = 1; i < self->n_ops; i++)
{
GskCurve curve;
float l;
float t[3];
int n;
gsk_curve_init (&curve, self->ops[i]);
g_array_append_val (array, ((CurvePoint) { i, 0, length }));
n = gsk_curve_get_curvature_points (&curve, t);
qsort (t, n, sizeof (float), cmpfloat);
for (int j = 0; j < n; j++)
{
l = gsk_curve_get_length_to (&curve, t[j]);
add_measure (&curve, length, tolerance, t[j], l, array);
}
l = gsk_curve_get_length (&curve);
add_measure (&curve, length, tolerance, 1, l, array);
length += l;
}
*out_length = length;
#if 0
g_print ("%lu ops, %u measure points\n", self->n_ops, array->len);
for (gsize i = 0; i < array->len; i++)
{
CurvePoint *pp = &g_array_index (array, CurvePoint, i);
const char *opname[] = { "M", "Z", "L", "Q", "C" };
GskPathOperation op = gsk_pathop_op (self->ops[pp->idx]);
g_print ("%lu %s %g -> %g\n", pp->idx, opname[op], pp->t, pp->length);
}
#endif
return array;
}
static void
gsk_standard_contour_free_measure (const GskContour *contour,
gpointer data)
{
g_array_free (data, TRUE);
}
static void
gsk_standard_contour_get_point (const GskContour *contour,
gpointer measure_data,
float distance,
GskRealPathPoint *result)
{
const GskStandardContour *self = (const GskStandardContour *) contour;
GArray *array = measure_data;
gsize i0, i1;
CurvePoint *p0, *p1;
if (self->n_ops == 1)
{
result->idx = 0;
result->t = 1;
return;
}
i0 = 0;
i1 = array->len - 1;
while (i0 + 1 < i1)
{
gsize i = (i0 + i1) / 2;
CurvePoint *p = &g_array_index (array, CurvePoint, i);
if (p->length < distance)
i0 = i;
else if (p->length > distance)
i1 = i;
else
{
result->idx = p->idx;
result->t = p->t;
return;
}
}
p0 = &g_array_index (array, CurvePoint, i0);
p1 = &g_array_index (array, CurvePoint, i1);
if (distance >= p1->length)
{
if (p1->idx == self->n_ops - 1)
{
result->idx = p1->idx;
result->t = 1;
}
else
{
result->idx = p1->idx + 1;
result->t = 0;
}
}
else
{
float fraction, t0;
g_assert (p0->idx == p1->idx || p0->t == 1);
t0 = p0->idx == p1->idx ? p0->t : 0;
result->idx = p1->idx;
fraction = (distance - p0->length) / (p1->length - p0->length);
g_assert (fraction >= 0.f && fraction <= 1.f);
result->t = t0 * (1 - fraction) + p1->t * fraction;
g_assert (result->t >= 0.f && result->t <= 1.f);
}
}
static float
gsk_standard_contour_get_distance (const GskContour *contour,
GskRealPathPoint *point,
gpointer measure_data)
{
GArray *array = measure_data;
gsize i0, i1;
CurvePoint *p0, *p1;
float fraction, t0;
if (G_UNLIKELY (point->idx == 0))
return 0;
i0 = 0;
i1 = array->len - 1;
while (i0 + 1 < i1)
{
gsize i = (i0 + i1) / 2;
CurvePoint *p = &g_array_index (array, CurvePoint, i);
if (p->idx > point->idx)
i1 = i;
else if (p->idx < point->idx)
i0 = i;
else if (p->t > point->t)
i1 = i;
else if (p->t < point->t)
i0 = i;
else
return p->length;
}
p0 = &g_array_index (array, CurvePoint, i0);
p1 = &g_array_index (array, CurvePoint, i1);
g_assert (p0->idx == p1->idx || p0->t == 1);
t0 = p0->idx == p1->idx ? p0->t : 0;
g_assert (p1->idx == point->idx);
g_assert (t0 <= point->t && point->t <= p1->t);
fraction = (point->t - t0) / (p1->t - t0);
g_assert (fraction >= 0.f && fraction <= 1.f);
return p0->length * (1 - fraction) + p1->length * fraction;
}
static const GskContourClass GSK_STANDARD_CONTOUR_CLASS =
{
sizeof (GskStandardContour),
@@ -622,6 +910,10 @@ static const GskContourClass GSK_STANDARD_CONTOUR_CLASS =
gsk_standard_contour_get_tangent,
gsk_standard_contour_get_curvature,
gsk_standard_contour_add_segment,
gsk_standard_contour_init_measure,
gsk_standard_contour_free_measure,
gsk_standard_contour_get_point,
gsk_standard_contour_get_distance,
};
/* You must ensure the contour has enough size allocated,
@@ -795,9 +1087,10 @@ gsk_contour_get_tangent (const GskContour *self,
float
gsk_contour_get_curvature (const GskContour *self,
GskRealPathPoint *point,
GskPathDirection direction,
graphene_point_t *center)
{
return self->klass->get_curvature (self, point, center);
return self->klass->get_curvature (self, point, direction, center);
}
void
@@ -810,6 +1103,38 @@ gsk_contour_add_segment (const GskContour *self,
self->klass->add_segment (self, builder, emit_move_to, start, end);
}
gpointer
gsk_contour_init_measure (const GskContour *self,
float tolerance,
float *out_length)
{
return self->klass->init_measure (self, tolerance, out_length);
}
void
gsk_contour_free_measure (const GskContour *self,
gpointer data)
{
self->klass->free_measure (self, data);
}
void
gsk_contour_get_point (const GskContour *self,
gpointer measure_data,
float distance,
GskRealPathPoint *result)
{
self->klass->get_point (self, measure_data, distance, result);
}
float
gsk_contour_get_distance (const GskContour *self,
GskRealPathPoint *point,
gpointer measure_data)
{
return self->klass->get_distance (self, point, measure_data);
}
/* }}} */
/* vim:set foldmethod=marker expandtab: */
+13
View File
@@ -72,6 +72,7 @@ void gsk_contour_get_tangent (const GskContou
graphene_vec2_t *tangent);
float gsk_contour_get_curvature (const GskContour *self,
GskRealPathPoint *point,
GskPathDirection direction,
graphene_point_t *center);
void gsk_contour_add_segment (const GskContour *self,
GskPathBuilder *builder,
@@ -79,5 +80,17 @@ void gsk_contour_add_segment (const GskContou
GskRealPathPoint *start,
GskRealPathPoint *end);
gpointer gsk_contour_init_measure (const GskContour *self,
float tolerance,
float *out_length);
void gsk_contour_free_measure (const GskContour *self,
gpointer data);
void gsk_contour_get_point (const GskContour *self,
gpointer measure_data,
float distance,
GskRealPathPoint *result);
float gsk_contour_get_distance (const GskContour *self,
GskRealPathPoint *point,
gpointer measure_data);
G_END_DECLS
+213
View File
@@ -0,0 +1,213 @@
/* Legendre-Gauss values,
* see https://pomax.github.io/bezierinfo/legendre-gauss.html
*/
#if 0
/* n = 64 */
static const double T[] = {
-0.0243502926634244325089558428537156614268871093149758091634531663960566965166295288529853061657116894882370493013671717560479926679408068852617342586968190919443025679363843727751902756254975073084367002129407854253246662805532069172532219089321005870178809284335033318073251039701073379759,
0.0243502926634244325089558428537156614268871093149758091634531663960566965166295288529853061657116894882370493013671717560479926679408068852617342586968190919443025679363843727751902756254975073084367002129407854253246662805532069172532219089321005870178809284335033318073251039701073379759,
-0.0729931217877990394495429419403374932441261816687788533563163323377395217254429050181833064967505478802134768007678458612956459126148837496307967995621683597067400860540057918571357609346700883624064782909888895547912499697295335516804810990011835717296819569741981551097569810739977931249,
0.0729931217877990394495429419403374932441261816687788533563163323377395217254429050181833064967505478802134768007678458612956459126148837496307967995621683597067400860540057918571357609346700883624064782909888895547912499697295335516804810990011835717296819569741981551097569810739977931249,
-0.1214628192961205544703764634922478782186836383371912940423495826006931832245070944213952236889690237679661122848626352437115925113582515415979746598665681268376919737373113667247142315234607397986222184384307059013512155412722263090766858403726100735651684437098923088469949297570988091677,
0.1214628192961205544703764634922478782186836383371912940423495826006931832245070944213952236889690237679661122848626352437115925113582515415979746598665681268376919737373113667247142315234607397986222184384307059013512155412722263090766858403726100735651684437098923088469949297570988091677,
-0.1696444204239928180373136297482698441999902667343778505894178746884342357796505591325925801106834127602396624627746208498838190598644711533868179088757129652678801285453336384132061358206434768209251779433993367981112053126660575920785488821886662635718276505127786854167528795165050389903,
0.1696444204239928180373136297482698441999902667343778505894178746884342357796505591325925801106834127602396624627746208498838190598644711533868179088757129652678801285453336384132061358206434768209251779433993367981112053126660575920785488821886662635718276505127786854167528795165050389903,
-0.217423643740007084149648748988822617578485831141222348630380401885689634737659235537163737740243604800759921292790013642836998201691226098978544332296437547642195961469059807833597096166848933098833151166287901339013986496737408125314858259377210847115061960167857239951500335854820530586,
0.217423643740007084149648748988822617578485831141222348630380401885689634737659235537163737740243604800759921292790013642836998201691226098978544332296437547642195961469059807833597096166848933098833151166287901339013986496737408125314858259377210847115061960167857239951500335854820530586,
-0.2646871622087674163739641725100201179804131362950932439559895448126206429452852982016450901649805445999078728714943692622330016257776575354105370883948495294882935681426154386660616476411740312465060150591301869544672050088454083442813632094277160007745547301572849406353682760306061929911,
0.2646871622087674163739641725100201179804131362950932439559895448126206429452852982016450901649805445999078728714943692622330016257776575354105370883948495294882935681426154386660616476411740312465060150591301869544672050088454083442813632094277160007745547301572849406353682760306061929911,
-0.3113228719902109561575126985601568835577153578680501269954571709858169098868398268719654999460149709757804582988077747605532896065842023340674450299515989484487746153929299031759475919924980452933324186984188982046762542556035347023744560814177013801414889023264804693830155588690576492164,
0.3113228719902109561575126985601568835577153578680501269954571709858169098868398268719654999460149709757804582988077747605532896065842023340674450299515989484487746153929299031759475919924980452933324186984188982046762542556035347023744560814177013801414889023264804693830155588690576492164,
-0.357220158337668115950442615046202531626264464640909112021237019340099177403802509741325589540743874845093675632547750287037622834793938695456980400958079292460482315821150714268593539935795231095157602025909339384694681190969656053235824652679875951093689200190014853543993102190088381483,
0.357220158337668115950442615046202531626264464640909112021237019340099177403802509741325589540743874845093675632547750287037622834793938695456980400958079292460482315821150714268593539935795231095157602025909339384694681190969656053235824652679875951093689200190014853543993102190088381483,
-0.4022701579639916036957667712601588487132652056150208082760431843129087214967261515969669708970990221669508217089555714806012046537594438323569293594638517933840725639831594134038262580440842200076281605641993773325072728778928440394419613403725280285705765326861533477990551765453978736181,
0.4022701579639916036957667712601588487132652056150208082760431843129087214967261515969669708970990221669508217089555714806012046537594438323569293594638517933840725639831594134038262580440842200076281605641993773325072728778928440394419613403725280285705765326861533477990551765453978736181,
-0.4463660172534640879849477147589151892067507578262501763082606820212937626970791295735937384813941473610238854736863966831464694923749954564921955859791688348936235671762050333408576202492209167272366373825152067680845198006626563761196191045700093968519269790165913301841545609485952718504,
0.4463660172534640879849477147589151892067507578262501763082606820212937626970791295735937384813941473610238854736863966831464694923749954564921955859791688348936235671762050333408576202492209167272366373825152067680845198006626563761196191045700093968519269790165913301841545609485952718504,
-0.4894031457070529574785263070219213908493732974637398373316540793240315585537584844752851087115581833443158831657759501916744927211636581386025171070582998790865902140901838128045602667002106847665927788023098753138400106615804847725751247952878407027140260429761863258319891988431055536872,
0.4894031457070529574785263070219213908493732974637398373316540793240315585537584844752851087115581833443158831657759501916744927211636581386025171070582998790865902140901838128045602667002106847665927788023098753138400106615804847725751247952878407027140260429761863258319891988431055536872,
-0.531279464019894545658013903544455247408525588734180238053268047166041778398245121448843253296460411619816073385211875151397248937264089998182375345915413219579220233566173902955487674957069948591213673456625912506280248298229907928060620469290406581396192419570799497688513058132396498814,
0.531279464019894545658013903544455247408525588734180238053268047166041778398245121448843253296460411619816073385211875151397248937264089998182375345915413219579220233566173902955487674957069948591213673456625912506280248298229907928060620469290406581396192419570799497688513058132396498814,
-0.5718956462026340342838781166591886431831910060912509932273284719418912212643223327597417735844776972648163821225207266145263395898251858906124801356522395225326954546582593857056725545247314092886133249957455688586118199388064447508712958637376347457406936802691416300157802889354368128467,
0.5718956462026340342838781166591886431831910060912509932273284719418912212643223327597417735844776972648163821225207266145263395898251858906124801356522395225326954546582593857056725545247314092886133249957455688586118199388064447508712958637376347457406936802691416300157802889354368128467,
-0.6111553551723932502488529710185489186961245593079718443367976666933088374650288148448667879830703867726577720666491772560110368248450475818132595468834493579434418252468978282181164008820769765174450056817468275783966537351796625224747700783378315186174632657840114512887287754747902924865,
0.6111553551723932502488529710185489186961245593079718443367976666933088374650288148448667879830703867726577720666491772560110368248450475818132595468834493579434418252468978282181164008820769765174450056817468275783966537351796625224747700783378315186174632657840114512887287754747902924865,
-0.6489654712546573398577612319934048855296904334732011728792502624366057598865738239773166627826358871699142531853930525866830933399401844502541092962631127742267449897116125748014270680393024011359139031312062573520509858894743036198986443014969748157931850178889912972291202354657382925509,
0.6489654712546573398577612319934048855296904334732011728792502624366057598865738239773166627826358871699142531853930525866830933399401844502541092962631127742267449897116125748014270680393024011359139031312062573520509858894743036198986443014969748157931850178889912972291202354657382925509,
-0.6852363130542332425635583710313763019356410785396718681324042749913611976548967332647625541234155413035075739348863233240851709341392873173633850612006618690218164007761541855237208605116527909791956398350719463021018362527198358286721239529091637248252469435642287693207506339068528700205,
0.6852363130542332425635583710313763019356410785396718681324042749913611976548967332647625541234155413035075739348863233240851709341392873173633850612006618690218164007761541855237208605116527909791956398350719463021018362527198358286721239529091637248252469435642287693207506339068528700205,
-0.7198818501716108268489402178319472447581380033149019526220473151184468592486433646042300919262498902882179891494724046747921544602557246455427317830132976771174504209146835854012577372395960646854355024460204286901035470812684876587693044068989973704915078171158689213412715251485203442313,
0.7198818501716108268489402178319472447581380033149019526220473151184468592486433646042300919262498902882179891494724046747921544602557246455427317830132976771174504209146835854012577372395960646854355024460204286901035470812684876587693044068989973704915078171158689213412715251485203442313,
-0.7528199072605318966118637748856939855517142713220871932461987761167722639636968539390413583009467924995905147153923286347693864945784890119950315095740891764880991728646942920208355501445550654259850385377192973526980795946453961077798744753892199929235882097232836682421729944934586281945,
0.7528199072605318966118637748856939855517142713220871932461987761167722639636968539390413583009467924995905147153923286347693864945784890119950315095740891764880991728646942920208355501445550654259850385377192973526980795946453961077798744753892199929235882097232836682421729944934586281945,
-0.7839723589433414076102205252137682840564141249898259334132759617476816578705098509357116190608002325895348207611752987335385494893726027026038902508685496606160441965948835252795524014713290879877269643684102005605450140247125536147801312017065532602835003540212221564314236937509990182173,
0.7839723589433414076102205252137682840564141249898259334132759617476816578705098509357116190608002325895348207611752987335385494893726027026038902508685496606160441965948835252795524014713290879877269643684102005605450140247125536147801312017065532602835003540212221564314236937509990182173,
-0.8132653151227975597419233380863033406981418225655972166956485149356586346082019870309280128411412936411423614767918756843380999442447282903502051218203273573634847203121451086379808399639198510674436238195505371716160648058477202993836014352158139813219612968106205248494087577632573534973,
0.8132653151227975597419233380863033406981418225655972166956485149356586346082019870309280128411412936411423614767918756843380999442447282903502051218203273573634847203121451086379808399639198510674436238195505371716160648058477202993836014352158139813219612968106205248494087577632573534973,
-0.840629296252580362751691544695873302982489823801755353928202683075593465893922171840726147868117503717663799561956411215937924134571068943700343442753760445948626598735504632170407243376224222403038093781056024445977626666740664628412660960413062370047183186652885532589557452614451434048,
0.840629296252580362751691544695873302982489823801755353928202683075593465893922171840726147868117503717663799561956411215937924134571068943700343442753760445948626598735504632170407243376224222403038093781056024445977626666740664628412660960413062370047183186652885532589557452614451434048,
-0.8659993981540928197607833850701575024125019187582496425664279511808356713122188567857456842034906362573453815878913951040194915987006979015304835979058725276345799813088989383312475641092775164460639450521468294104011206574786429237252678172922104036725327539940502197291939132802457917836,
0.8659993981540928197607833850701575024125019187582496425664279511808356713122188567857456842034906362573453815878913951040194915987006979015304835979058725276345799813088989383312475641092775164460639450521468294104011206574786429237252678172922104036725327539940502197291939132802457917836,
-0.8893154459951141058534040382728516224291944615104521893194744566084811090577722526400445910623711480590529533188832105988657269430913287263821624762648137092066620632787986348052306840101775313644572400860845559833367997001666659907951051347410546710134120144598833115095140475669485797579,
0.8893154459951141058534040382728516224291944615104521893194744566084811090577722526400445910623711480590529533188832105988657269430913287263821624762648137092066620632787986348052306840101775313644572400860845559833367997001666659907951051347410546710134120144598833115095140475669485797579,
-0.9105221370785028057563806680083298610134880848883640292531723714467102234556291968179018775780308458024302103848451312741663820589200520720207891653884985710130867134073520525932445557074805974235006810370309087879564826639263972805682465506594098949560288847385983395160311034445386606259,
0.9105221370785028057563806680083298610134880848883640292531723714467102234556291968179018775780308458024302103848451312741663820589200520720207891653884985710130867134073520525932445557074805974235006810370309087879564826639263972805682465506594098949560288847385983395160311034445386606259,
-0.9295691721319395758214901545592256073474270144297154975928116833612430986265594515998834499355844736686512805129688214992047597092114291955925880175797899765980745854426738149516325837607227287481909072315347776012991222301207304052068204069335766550173941103055407746774520789612843561385,
0.9295691721319395758214901545592256073474270144297154975928116833612430986265594515998834499355844736686512805129688214992047597092114291955925880175797899765980745854426738149516325837607227287481909072315347776012991222301207304052068204069335766550173941103055407746774520789612843561385,
-0.9464113748584028160624814913472647952793949717952331902317789712973664402149436591260928179188420533516264142755452159723722786167537167514691534968355366202934342465086995943893699962972237343218079763936958985487264411542890941861254842843026890160131607678957282346112697993618567018237,
0.9464113748584028160624814913472647952793949717952331902317789712973664402149436591260928179188420533516264142755452159723722786167537167514691534968355366202934342465086995943893699962972237343218079763936958985487264411542890941861254842843026890160131607678957282346112697993618567018237,
-0.9610087996520537189186141218971572067621146110378459494461586158623919945488992563976780806866203786216001498788310714552847469661399216303755820947005848739467276644122915754949838610353627723679982220628115164983443994552616161584523205789167087822341423097206088828267065770404672828066,
0.9610087996520537189186141218971572067621146110378459494461586158623919945488992563976780806866203786216001498788310714552847469661399216303755820947005848739467276644122915754949838610353627723679982220628115164983443994552616161584523205789167087822341423097206088828267065770404672828066,
-0.9733268277899109637418535073522726680261452944551741758819139781978152256958453749994966038154125547612207903105020176172420237675899907788807087542221018040460410464083361271842759039530092449625891215101984663282728542290395875313124045226564547294745437773482395329023327909760431499638,
0.9733268277899109637418535073522726680261452944551741758819139781978152256958453749994966038154125547612207903105020176172420237675899907788807087542221018040460410464083361271842759039530092449625891215101984663282728542290395875313124045226564547294745437773482395329023327909760431499638,
-0.9833362538846259569312993021568311169452475066237403837464872131233426128415470535606559721330818003585532628124845662897410684694651251174207713020897795837892725294581710205598344576799985346970638130204876060998657059283079767876980544166132523941283823202290746667358872631036031924711,
0.9833362538846259569312993021568311169452475066237403837464872131233426128415470535606559721330818003585532628124845662897410684694651251174207713020897795837892725294581710205598344576799985346970638130204876060998657059283079767876980544166132523941283823202290746667358872631036031924711,
-0.9910133714767443207393823834433031136413494453907904852225427459378131658644129997345108950133770434340330151289100150097018332483423277136039914249575686591612502752158650205954671083696496347591169012794322303027309768195334920157669446268175983954105533989275308193580349506657360682085,
0.9910133714767443207393823834433031136413494453907904852225427459378131658644129997345108950133770434340330151289100150097018332483423277136039914249575686591612502752158650205954671083696496347591169012794322303027309768195334920157669446268175983954105533989275308193580349506657360682085,
-0.9963401167719552793469245006763991232098575063402266121352522199507030568202208530946066801021703916301511794658310735397567341036554686814952726523955953805437164277655915410358813984246580862850974195805395101678543649116458555272523253307828290553873260588621490898443701779725568118502,
0.9963401167719552793469245006763991232098575063402266121352522199507030568202208530946066801021703916301511794658310735397567341036554686814952726523955953805437164277655915410358813984246580862850974195805395101678543649116458555272523253307828290553873260588621490898443701779725568118502,
-0.9993050417357721394569056243456363119697121916756087760628072954617646543505331997843242376462639434945376776512170265314011232493020401570891594274831367800115383317335285468800574240152992751785027563437707875403545865305271045717258142571193695943317890367167086616955235477529427992282,
0.9993050417357721394569056243456363119697121916756087760628072954617646543505331997843242376462639434945376776512170265314011232493020401570891594274831367800115383317335285468800574240152992751785027563437707875403545865305271045717258142571193695943317890367167086616955235477529427992282
};
static const double C[] = {
0.0486909570091397203833653907347499124426286922838743305086688042456914190998246107310291565645676057401607079939845156005172257043376703767287395573765236401039685866479381075274920900511719320271157129622463682509122641788910270632229694394595885032921037399187298767076084601033342936131,
0.0486909570091397203833653907347499124426286922838743305086688042456914190998246107310291565645676057401607079939845156005172257043376703767287395573765236401039685866479381075274920900511719320271157129622463682509122641788910270632229694394595885032921037399187298767076084601033342936131,
0.0485754674415034269347990667839781136875565447049294857111516761025158193093697039229163427633930410186232149083923688162761488505704450697417589593116703853157329164894580165517236877241308351214870169600093357854651930986960906313726182992933363325614247750209880050786299287510692780499,
0.0485754674415034269347990667839781136875565447049294857111516761025158193093697039229163427633930410186232149083923688162761488505704450697417589593116703853157329164894580165517236877241308351214870169600093357854651930986960906313726182992933363325614247750209880050786299287510692780499,
0.048344762234802957169769527158017809703692550609501080629442201445249828946429202156764153264348308119169811534137999799779908820312744765416129733427088646813066886130539178187597540312913636916139844188190193872629488730769015964208394624398401975043997268903006190530430762197842013971,
0.048344762234802957169769527158017809703692550609501080629442201445249828946429202156764153264348308119169811534137999799779908820312744765416129733427088646813066886130539178187597540312913636916139844188190193872629488730769015964208394624398401975043997268903006190530430762197842013971,
0.0479993885964583077281261798713460699543167134714936209446323930933335214619650277588138568504103427609283146728470455041360837549685364869161566863222680599110109210456299588352028330169041000166382937545505655464884266691630625402297821494221827392164049587946530563778771030124675514431,
0.0479993885964583077281261798713460699543167134714936209446323930933335214619650277588138568504103427609283146728470455041360837549685364869161566863222680599110109210456299588352028330169041000166382937545505655464884266691630625402297821494221827392164049587946530563778771030124675514431,
0.0475401657148303086622822069442231716408252512625387521584740318784735191312349586041971325618543660076682369564304738487584849740943805934034367382833518752314207901993991333786062812015195073547884746598535775062676699885664167707011249029305697669004958515813436770491520105115843742005,
0.0475401657148303086622822069442231716408252512625387521584740318784735191312349586041971325618543660076682369564304738487584849740943805934034367382833518752314207901993991333786062812015195073547884746598535775062676699885664167707011249029305697669004958515813436770491520105115843742005,
0.0469681828162100173253262857545810751998975284738125649829240886861900500181800807437012381630302198876925642461830694029139318555787845567143614289552410495903601238284556145544858090965965782916339169651505119399637862876053945518410353459767034026687936026945199383607112976484520939933,
0.0469681828162100173253262857545810751998975284738125649829240886861900500181800807437012381630302198876925642461830694029139318555787845567143614289552410495903601238284556145544858090965965782916339169651505119399637862876053945518410353459767034026687936026945199383607112976484520939933,
0.0462847965813144172959532492322611849696503075324468007778340818364698861774606986244241539105685321088517142947579291476238551538798963436740600968513359005801910700069462154098456091711311098901749803777735222026075473081311483686560830539773763176758567914860207820170792365910140063798,
0.0462847965813144172959532492322611849696503075324468007778340818364698861774606986244241539105685321088517142947579291476238551538798963436740600968513359005801910700069462154098456091711311098901749803777735222026075473081311483686560830539773763176758567914860207820170792365910140063798,
0.0454916279274181444797709969712690588873234618023998968168834081606504637618082102750954507142497706775055424364453740562113890878382679420378787427100982909191308430750899201141096789461078632697297091763378573830284133736378128577579722120264252594541491899441765769262904055702701625378,
0.0454916279274181444797709969712690588873234618023998968168834081606504637618082102750954507142497706775055424364453740562113890878382679420378787427100982909191308430750899201141096789461078632697297091763378573830284133736378128577579722120264252594541491899441765769262904055702701625378,
0.0445905581637565630601347100309448432940237999912217256432193286861948363377761089569585678875932857237669096941854082976565514031401996407675401022860761183118504326746863327792604337217763335682212515058414863183914930810334329596384915832703655935958010948424747251920190851700662833367,
0.0445905581637565630601347100309448432940237999912217256432193286861948363377761089569585678875932857237669096941854082976565514031401996407675401022860761183118504326746863327792604337217763335682212515058414863183914930810334329596384915832703655935958010948424747251920190851700662833367,
0.0435837245293234533768278609737374809227888974971180150532193925502569499020021803936448815937567079991401855477391110804568848623412043870399620479222000249538880795788245633051476595555730388360811011823841525667998427392843673284072004068821750061964976796287623004834501604656318714989,
0.0435837245293234533768278609737374809227888974971180150532193925502569499020021803936448815937567079991401855477391110804568848623412043870399620479222000249538880795788245633051476595555730388360811011823841525667998427392843673284072004068821750061964976796287623004834501604656318714989,
0.0424735151236535890073397679088173661655466481806496697314607722055245433487169327182398988553670128358787507582463602377168227019625334754497484024668087975720049504975593281010888062806587161032924284354938115463233015024659299046001504100674918329532481611571863222497170398830691222425,
0.0424735151236535890073397679088173661655466481806496697314607722055245433487169327182398988553670128358787507582463602377168227019625334754497484024668087975720049504975593281010888062806587161032924284354938115463233015024659299046001504100674918329532481611571863222497170398830691222425,
0.0412625632426235286101562974736380477399306355305474105429034779122704951178045914463267035032832336161816547420067160277921114474557623647771372636679857599931025531633255548770293397336318597716427093310378312957479805159734598610664983115148350548735211568465338522875618805992499897174,
0.0412625632426235286101562974736380477399306355305474105429034779122704951178045914463267035032832336161816547420067160277921114474557623647771372636679857599931025531633255548770293397336318597716427093310378312957479805159734598610664983115148350548735211568465338522875618805992499897174,
0.0399537411327203413866569261283360739186769506703336301114037026981570543670430333260307390357287606111017588757685176701688554806178713759519003171090525332423003042251947304213502522332118258365256241174986409729902714098049024753746340158430732115642207673265332738358717839602955875715,
0.0399537411327203413866569261283360739186769506703336301114037026981570543670430333260307390357287606111017588757685176701688554806178713759519003171090525332423003042251947304213502522332118258365256241174986409729902714098049024753746340158430732115642207673265332738358717839602955875715,
0.0385501531786156291289624969468089910127871122017180319662378854088005271323682681394418540442928363090545214563022868422017877042243007014244875098498616146404178795110038170109976252865902624380463581094085479557660525450020049773872343621719025128277593787164021147974906095237533202082,
0.0385501531786156291289624969468089910127871122017180319662378854088005271323682681394418540442928363090545214563022868422017877042243007014244875098498616146404178795110038170109976252865902624380463581094085479557660525450020049773872343621719025128277593787164021147974906095237533202082,
0.0370551285402400460404151018095833750834649453056563021747536272028091562122966687178302646649066832960609370472485057031765338738734008482025086366647963664178752038995704175623165041724901843573087856883034472545386037691055680911138721623610172486110313241291773258491882452773847899443,
0.0370551285402400460404151018095833750834649453056563021747536272028091562122966687178302646649066832960609370472485057031765338738734008482025086366647963664178752038995704175623165041724901843573087856883034472545386037691055680911138721623610172486110313241291773258491882452773847899443,
0.0354722132568823838106931467152459479480946310024100946926514848199381113651392962399922996268087884509143420993419937430515415557908457195618550238075571721209638845910166697234073788332647695349442265578792857058786796417110738673392400570019770741873271724201517438135222598792344040215,
0.0354722132568823838106931467152459479480946310024100946926514848199381113651392962399922996268087884509143420993419937430515415557908457195618550238075571721209638845910166697234073788332647695349442265578792857058786796417110738673392400570019770741873271724201517438135222598792344040215,
0.0338051618371416093915654821107254310210499263140045346675500650400323727745785853730452808963944098691936344225349051741060036935288424090581463711756382878498537611980973238606529148664990420534952057130296232922368792280098852092993207644225150541876980292972087619863453425206929192216,
0.0338051618371416093915654821107254310210499263140045346675500650400323727745785853730452808963944098691936344225349051741060036935288424090581463711756382878498537611980973238606529148664990420534952057130296232922368792280098852092993207644225150541876980292972087619863453425206929192216,
0.032057928354851553585467504347898716966221573881398062250169407854535275399124366530227987935629046729162364779969274126431870966979526186907589490002269660893281421728773647001279141626157958271220102615163092206489916992120482595587916535390136003611498634162765724522022671474313619317,
0.032057928354851553585467504347898716966221573881398062250169407854535275399124366530227987935629046729162364779969274126431870966979526186907589490002269660893281421728773647001279141626157958271220102615163092206489916992120482595587916535390136003611498634162765724522022671474313619317,
0.030234657072402478867974059819548659158281397768481241636026542045969161851838118212761980885178641520596873511042783163461341979185470882574743804555268086640389062237383427702813367624714014426121485626242067362445894463989335423458464954799181190120473168677930333898873084606011285311,
0.030234657072402478867974059819548659158281397768481241636026542045969161851838118212761980885178641520596873511042783163461341979185470882574743804555268086640389062237383427702813367624714014426121485626242067362445894463989335423458464954799181190120473168677930333898873084606011285311,
0.0283396726142594832275113052002373519812075841257543359907955185084500175712880712901834579816476269393013386531176072296695948860841466158639973753393323262188023471133258509422081952937349849822864752636994881600343083839805990853930436233762729622213044478376753949590318846038229829528,
0.0283396726142594832275113052002373519812075841257543359907955185084500175712880712901834579816476269393013386531176072296695948860841466158639973753393323262188023471133258509422081952937349849822864752636994881600343083839805990853930436233762729622213044478376753949590318846038229829528,
0.0263774697150546586716917926252251856755993308422457184496156736853021592428967790284780487213653480867620409279447766944383920384284787790772384251090745670478105870527396429136326932261251511732466974897397268573168068852344129736214469830280087710575094607457344820944885011053938108899,
0.0263774697150546586716917926252251856755993308422457184496156736853021592428967790284780487213653480867620409279447766944383920384284787790772384251090745670478105870527396429136326932261251511732466974897397268573168068852344129736214469830280087710575094607457344820944885011053938108899,
0.0243527025687108733381775504090689876499784155133784119819985685535536787083770723737264828464464223276155821319330210193549896426801083040150047332857692873011433649334477370145389017577189505240415125600908800786897201425473757275187332157593198572919772969833130729981971352463730545469,
0.0243527025687108733381775504090689876499784155133784119819985685535536787083770723737264828464464223276155821319330210193549896426801083040150047332857692873011433649334477370145389017577189505240415125600908800786897201425473757275187332157593198572919772969833130729981971352463730545469,
0.0222701738083832541592983303841550024229592905997594051455205429744914460867081990116647982811451138592401156680063927909718825845915896692701716212710541472344073624315399429951255221519263275095347974129106415903376085208797420439500915674568159744176912567285070988940509294826076696882,
0.0222701738083832541592983303841550024229592905997594051455205429744914460867081990116647982811451138592401156680063927909718825845915896692701716212710541472344073624315399429951255221519263275095347974129106415903376085208797420439500915674568159744176912567285070988940509294826076696882,
0.0201348231535302093723403167285438970895266801007919519220072343276769828211923597982299498416998597995443052252531684909219367615574440281549241161294448697202959593344989612626641188010558013085389491205901106884167596038790695150496733123662891637942237462337673353651179115491957031948,
0.0201348231535302093723403167285438970895266801007919519220072343276769828211923597982299498416998597995443052252531684909219367615574440281549241161294448697202959593344989612626641188010558013085389491205901106884167596038790695150496733123662891637942237462337673353651179115491957031948,
0.0179517157756973430850453020011193688971673570364158572977184273569247295870620984743089140579199272107974903016785911970727080884655646148340637373001805876560334052431930062983734905886704331100259778249929425439377011315288821865303197904492848823994202996722656114004109123107733596987,
0.0179517157756973430850453020011193688971673570364158572977184273569247295870620984743089140579199272107974903016785911970727080884655646148340637373001805876560334052431930062983734905886704331100259778249929425439377011315288821865303197904492848823994202996722656114004109123107733596987,
0.0157260304760247193219659952975397944260290098431565121528943932284210502164124556525745628476326997189475680077625258949765335021586482683126547283634704087193102431454662772463321304938516661086261262080252305539171654570677889578063634007609097342035360186636479612243231917699790225637,
0.0157260304760247193219659952975397944260290098431565121528943932284210502164124556525745628476326997189475680077625258949765335021586482683126547283634704087193102431454662772463321304938516661086261262080252305539171654570677889578063634007609097342035360186636479612243231917699790225637,
0.0134630478967186425980607666859556841084257719773496708184682785221983598894666268489697837056105038485845901773961664652581563686185523959473293683490869846700009741156668864960127745507806046701586435579547632680339906665338521813319281296935586498194608460412423723103161161922347608637,
0.0134630478967186425980607666859556841084257719773496708184682785221983598894666268489697837056105038485845901773961664652581563686185523959473293683490869846700009741156668864960127745507806046701586435579547632680339906665338521813319281296935586498194608460412423723103161161922347608637,
0.011168139460131128818590493019208135072778797816827287215251362273969701224836131369547661822970774719521543690039908073147476182135228738610704246958518755712518444434075738269866120460156365855324768445411463643114925829148750923090201475035559533993035986264487097245733097728698218563,
0.011168139460131128818590493019208135072778797816827287215251362273969701224836131369547661822970774719521543690039908073147476182135228738610704246958518755712518444434075738269866120460156365855324768445411463643114925829148750923090201475035559533993035986264487097245733097728698218563,
0.0088467598263639477230309146597306476951762660792204997984715769296110380005985367341694286322550520156167431790573509593010611842062630262878798782558974712042810219159674181580449655112696028911646066461502678711637780164986283350190669684468398617127841853445303466680698660632269500149,
0.0088467598263639477230309146597306476951762660792204997984715769296110380005985367341694286322550520156167431790573509593010611842062630262878798782558974712042810219159674181580449655112696028911646066461502678711637780164986283350190669684468398617127841853445303466680698660632269500149,
0.0065044579689783628561173603999812667711317610549523400952448792575685125717613068203530526491113296049409911387320826711045787146267036866881961532403342811327869183281273743976710008917886491097375367147212074243884772614562628844975421736416404173672075979097191581386023407454532945934,
0.0065044579689783628561173603999812667711317610549523400952448792575685125717613068203530526491113296049409911387320826711045787146267036866881961532403342811327869183281273743976710008917886491097375367147212074243884772614562628844975421736416404173672075979097191581386023407454532945934,
0.0041470332605624676352875357285514153133028192536848024628763661431834776690157393776820933106187137592011723199002845429836606307797425496666456172753165824787973801175029578301513761259541022471768825518482406145696380621686627285992715643614469568410535180218496973657001203470470418364,
0.0041470332605624676352875357285514153133028192536848024628763661431834776690157393776820933106187137592011723199002845429836606307797425496666456172753165824787973801175029578301513761259541022471768825518482406145696380621686627285992715643614469568410535180218496973657001203470470418364,
0.0017832807216964329472960791449719331799593472719279556695308063655858546954239803486698215802150348282744786016134857283616955449868451969230490863774274598030023211055562492709717566919237924255297982774711177411074145151155610163293142044147991553384925940046957893721166251082473659733,
0.0017832807216964329472960791449719331799593472719279556695308063655858546954239803486698215802150348282744786016134857283616955449868451969230490863774274598030023211055562492709717566919237924255297982774711177411074145151155610163293142044147991553384925940046957893721166251082473659733
};
#else
/* n = 32 */
static double T[] = {
-0.0483076656877383162348125704405021636908472517308488971677937345463685926042778777794060365911173780988289503411375793689757446357461295741679964108035347980667582792392651327368009453047606446744575790523465655622949909588624860214137051585425884056992683442137333250625173849291299678673,
0.0483076656877383162348125704405021636908472517308488971677937345463685926042778777794060365911173780988289503411375793689757446357461295741679964108035347980667582792392651327368009453047606446744575790523465655622949909588624860214137051585425884056992683442137333250625173849291299678673,
-0.1444719615827964934851863735988106522038459913156355521379528938242184438164519731102406769974924713989580220758441301598578946580142268413547299935841673092513202403499286272686350814272974392746706128556678811982653393383080797337231702069432462445053984587997153683967433095128570624414,
0.1444719615827964934851863735988106522038459913156355521379528938242184438164519731102406769974924713989580220758441301598578946580142268413547299935841673092513202403499286272686350814272974392746706128556678811982653393383080797337231702069432462445053984587997153683967433095128570624414,
-0.2392873622521370745446032091655015206088554219602530155470960995597029133039943915553593695844147813728958071901224632260145752503694970545640339873418480550362677768010887468668377893757173424222709744116861683634989914911762187599464033126988486345234374380695224452457957624756811128321,
0.2392873622521370745446032091655015206088554219602530155470960995597029133039943915553593695844147813728958071901224632260145752503694970545640339873418480550362677768010887468668377893757173424222709744116861683634989914911762187599464033126988486345234374380695224452457957624756811128321,
-0.3318686022821276497799168057301879961957751368050598360182296306285376829657438169809731852312743263005943551508559377834274303920771100489026913715847854727626540340157368609696698131829681988642689780208633461925468064919389286805624602715005948661328152252049795463242055567997437182143,
0.3318686022821276497799168057301879961957751368050598360182296306285376829657438169809731852312743263005943551508559377834274303920771100489026913715847854727626540340157368609696698131829681988642689780208633461925468064919389286805624602715005948661328152252049795463242055567997437182143,
-0.4213512761306353453641194361724264783358772886324433305416613404557190462549837315607633055675740638739884093394574651160978879545562247406839036854173715776910866941643197988581928900702286425821151586000969947406313405310082646561917980302543820974679501841964453794193724645925031841919,
0.4213512761306353453641194361724264783358772886324433305416613404557190462549837315607633055675740638739884093394574651160978879545562247406839036854173715776910866941643197988581928900702286425821151586000969947406313405310082646561917980302543820974679501841964453794193724645925031841919,
-0.5068999089322293900237474743778212301802836995994354639743662809707712640478764442266190213124522047999876916596854537447047905434649918210338296049592120273725464263651562560829050004258268002241145951271730860506703690843719936432852920782304931272053564539127514959875734718036950073563,
0.5068999089322293900237474743778212301802836995994354639743662809707712640478764442266190213124522047999876916596854537447047905434649918210338296049592120273725464263651562560829050004258268002241145951271730860506703690843719936432852920782304931272053564539127514959875734718036950073563,
-0.5877157572407623290407454764018268584509401154544205727031788473129228586684474311408145102018661764979429510790747919023774933113319119601088669936958908618326367715806216053155906936017362413244183150445492317940727345571648726363597097311647731726438279098059670236086983675374932643925,
0.5877157572407623290407454764018268584509401154544205727031788473129228586684474311408145102018661764979429510790747919023774933113319119601088669936958908618326367715806216053155906936017362413244183150445492317940727345571648726363597097311647731726438279098059670236086983675374932643925,
-0.6630442669302152009751151686632383689770222859605053010170834964924461749232229404368981536611965356686820332804126742949900731319113817214392193185613161549689934301410316417342588149871686184296988807305719690974644891055567340650986465615021143958920599684258616066247948224049997371166,
0.6630442669302152009751151686632383689770222859605053010170834964924461749232229404368981536611965356686820332804126742949900731319113817214392193185613161549689934301410316417342588149871686184296988807305719690974644891055567340650986465615021143958920599684258616066247948224049997371166,
-0.732182118740289680387426665091267146630270483506629100821139573270385253587797727611292298988652560055905228466313310601075333829094630570926240639601009902567982815376254840388565733846030450161774620971196087756484387383432502715118096615117242484073636640563609696801484680439912327302,
0.732182118740289680387426665091267146630270483506629100821139573270385253587797727611292298988652560055905228466313310601075333829094630570926240639601009902567982815376254840388565733846030450161774620971196087756484387383432502715118096615117242484073636640563609696801484680439912327302,
-0.7944837959679424069630972989704289020954794016388354532507582449720593922816426654241878967890821228397041480126630294067578180914548706957761322921470535094589673860419616615738928385807346185892317514562489971543238450942224396667500582904031225063621511429185567036727089257387570529468,
0.7944837959679424069630972989704289020954794016388354532507582449720593922816426654241878967890821228397041480126630294067578180914548706957761322921470535094589673860419616615738928385807346185892317514562489971543238450942224396667500582904031225063621511429185567036727089257387570529468,
-0.849367613732569970133693004967742538954886793049759233100219598613724656141562558741881463752754991143937635778596582088915769685796612254240615386941355933272723068952531445772190363422003834495043219316062885999846179078139659341918527603834809670576387535564876596379488780285979062125,
0.849367613732569970133693004967742538954886793049759233100219598613724656141562558741881463752754991143937635778596582088915769685796612254240615386941355933272723068952531445772190363422003834495043219316062885999846179078139659341918527603834809670576387535564876596379488780285979062125,
-0.8963211557660521239653072437192122684789964967957595765636154129650249794910409173494503783167666654202705333374285522819507600044591355080910768854012859468015827508424619812224062460791781333400979810176198916239783226706506012473250929962326307746466256167673927887144428859779028909399,
0.8963211557660521239653072437192122684789964967957595765636154129650249794910409173494503783167666654202705333374285522819507600044591355080910768854012859468015827508424619812224062460791781333400979810176198916239783226706506012473250929962326307746466256167673927887144428859779028909399,
-0.9349060759377396891709191348354093255286714322828372184584037398118161947182932855418880831417927728359606280450921427988850058691931014887248988124656348299653052688344696135840215712191162135178273756415771123010111796122671724143565383396162107206772781551029308751511942924942333859805,
0.9349060759377396891709191348354093255286714322828372184584037398118161947182932855418880831417927728359606280450921427988850058691931014887248988124656348299653052688344696135840215712191162135178273756415771123010111796122671724143565383396162107206772781551029308751511942924942333859805,
-0.9647622555875064307738119281182749603888952204430187193220113218370995254867038008243801877562227002840740910741483519987441236283464394249183812395373150090695515823078220949436846111682404866338388944248976976566275875721000356873959697266702651250019105084704924793016185368873243713355,
0.9647622555875064307738119281182749603888952204430187193220113218370995254867038008243801877562227002840740910741483519987441236283464394249183812395373150090695515823078220949436846111682404866338388944248976976566275875721000356873959697266702651250019105084704924793016185368873243713355,
-0.9856115115452683354001750446309019786323957143358063182107821705820305847193755946663846485510970266115353839862364606643634021712823093784875255943834038377710426488328772047833289470320023596895438028281274741367781028592272459887917924171204666683239464005128153533797603112851826904814,
0.9856115115452683354001750446309019786323957143358063182107821705820305847193755946663846485510970266115353839862364606643634021712823093784875255943834038377710426488328772047833289470320023596895438028281274741367781028592272459887917924171204666683239464005128153533797603112851826904814,
-0.9972638618494815635449811286650407271385376637294611593011185457862359083917418520130456693085426416474280482200936551645510686196373231416035137741332968299789863385253514914078766236061488136738023162574655835389902337937054326098485227311719825229066712510246574949376367552421728646398,
0.9972638618494815635449811286650407271385376637294611593011185457862359083917418520130456693085426416474280482200936551645510686196373231416035137741332968299789863385253514914078766236061488136738023162574655835389902337937054326098485227311719825229066712510246574949376367552421728646398
};
static double C[] = {
0.0965400885147278005667648300635757947368606312355700687323182099577497758679466512968173871061464644599963197828969869820251559172455698832434930732077927850876632725829187045819145660710266452161095406358159608874152584850413283587913891015545638518881205600825069096855488296437485836866,
0.0965400885147278005667648300635757947368606312355700687323182099577497758679466512968173871061464644599963197828969869820251559172455698832434930732077927850876632725829187045819145660710266452161095406358159608874152584850413283587913891015545638518881205600825069096855488296437485836866,
0.0956387200792748594190820022041311005948905081620055509529898509437067444366006256133614167190847508238474888230077112990752876436158047205555474265705582078453283640212465537132165041268773645168746774530146140911679782502276289938840330631903789120176765314495900053061764438990021439069,
0.0956387200792748594190820022041311005948905081620055509529898509437067444366006256133614167190847508238474888230077112990752876436158047205555474265705582078453283640212465537132165041268773645168746774530146140911679782502276289938840330631903789120176765314495900053061764438990021439069,
0.0938443990808045656391802376681172600361000757462364500506275696355695118623098075097804207682530277555307864917078828352419853248607668520631751470962234105835015158485760721979732297206950719908744248285672032436598213262204039212897239890934116841559005147755270269705682414708355646603,
0.0938443990808045656391802376681172600361000757462364500506275696355695118623098075097804207682530277555307864917078828352419853248607668520631751470962234105835015158485760721979732297206950719908744248285672032436598213262204039212897239890934116841559005147755270269705682414708355646603,
0.0911738786957638847128685771116370625448614132753900053231278739777031520613017513597426417145878622654027367650308019870251963114683369110451524174258161390823876554910693202594383388549640738095422966058367070348943662290656339592299608558384147559830707904449930677260444604329157917977,
0.0911738786957638847128685771116370625448614132753900053231278739777031520613017513597426417145878622654027367650308019870251963114683369110451524174258161390823876554910693202594383388549640738095422966058367070348943662290656339592299608558384147559830707904449930677260444604329157917977,
0.0876520930044038111427714627518022875484497217017572223192228034747061150211380239263021665771581379364685191248848158059408000065275041643745927401342920150588893827207354226012701872322225514682178439577327346929209121046816487338309068375228210705166692551938339727096609740531893725675,
0.0876520930044038111427714627518022875484497217017572223192228034747061150211380239263021665771581379364685191248848158059408000065275041643745927401342920150588893827207354226012701872322225514682178439577327346929209121046816487338309068375228210705166692551938339727096609740531893725675,
0.0833119242269467552221990746043486115387468839428344598401864047287594069244380966536255650452315042012372905572506028852130723585016898197140339352228963465326746426938359210160503509807644396182380868089959855742801355208471205261406307895519604387550841954817025499019984032594036141439,
0.0833119242269467552221990746043486115387468839428344598401864047287594069244380966536255650452315042012372905572506028852130723585016898197140339352228963465326746426938359210160503509807644396182380868089959855742801355208471205261406307895519604387550841954817025499019984032594036141439,
0.078193895787070306471740918828306671039786798482159190307481553869493700115196435401943819761440851294456424770323467367505109006517482028994114252939401250416132320553639542341400437522236191275346323130525969269563653003188829786549728825182082678498917784036375053244425839341945385297,
0.078193895787070306471740918828306671039786798482159190307481553869493700115196435401943819761440851294456424770323467367505109006517482028994114252939401250416132320553639542341400437522236191275346323130525969269563653003188829786549728825182082678498917784036375053244425839341945385297,
0.0723457941088485062253993564784877916043369833018248707397632823511765345816800402874475958591657429073027694582930574378890633404841054620298756279975430795706338162404545590689277985270140590721779502609564199074051863640176937117952488466002340085264819537808079947788437998042296495822,
0.0723457941088485062253993564784877916043369833018248707397632823511765345816800402874475958591657429073027694582930574378890633404841054620298756279975430795706338162404545590689277985270140590721779502609564199074051863640176937117952488466002340085264819537808079947788437998042296495822,
0.0658222227763618468376500637069387728775364473732465153710916696852412442018627316280044447764609054151761388378861151807154113495715653711918644796313239555117970398473141615070299152284100887258072240524028885129828725430021172354299810423059697133688823072212214503334259555369485963074,
0.0658222227763618468376500637069387728775364473732465153710916696852412442018627316280044447764609054151761388378861151807154113495715653711918644796313239555117970398473141615070299152284100887258072240524028885129828725430021172354299810423059697133688823072212214503334259555369485963074,
0.0586840934785355471452836373001708867501204674575467587150032786132877518019090643743123653437052116901895704813134467814193905269714480573030647540887991405215103758723074481312705449946311993670933802369300463315125015975216910705047901943865293781921122370996257470349807212516159332678,
0.0586840934785355471452836373001708867501204674575467587150032786132877518019090643743123653437052116901895704813134467814193905269714480573030647540887991405215103758723074481312705449946311993670933802369300463315125015975216910705047901943865293781921122370996257470349807212516159332678,
0.0509980592623761761961632446895216952601847767397628437069071236525030510385137821267442193868358292147899714519363571211100873456269865150186456681043804358654826791768545393024953758025593924464295555854744882720755747096079325496814455853004350452095212995888025282619932613606999567133,
0.0509980592623761761961632446895216952601847767397628437069071236525030510385137821267442193868358292147899714519363571211100873456269865150186456681043804358654826791768545393024953758025593924464295555854744882720755747096079325496814455853004350452095212995888025282619932613606999567133,
0.0428358980222266806568786466061255284928108575989407395620219408911043916962572261359138025961596979511472539467367407419206021900868371610612953162236233351132214438513203223655531564777278515080476421262443325932320214191168239648611793958596884827086182431203349730049744697408543115307,
0.0428358980222266806568786466061255284928108575989407395620219408911043916962572261359138025961596979511472539467367407419206021900868371610612953162236233351132214438513203223655531564777278515080476421262443325932320214191168239648611793958596884827086182431203349730049744697408543115307,
0.0342738629130214331026877322523727069948402029116274337814057454192310522168984446294442724624445760666244242305266023810860790282088335398182296698622433517061843276344829146573593201201081743714879684153735672789104567624853712011151505225193933019375481618760594889854480408562043658635,
0.0342738629130214331026877322523727069948402029116274337814057454192310522168984446294442724624445760666244242305266023810860790282088335398182296698622433517061843276344829146573593201201081743714879684153735672789104567624853712011151505225193933019375481618760594889854480408562043658635,
0.0253920653092620594557525897892240292875540475469487209362512822192154788532376645960457016338988332029324531233401833547954942765653767672102838323550828207273795044402516181251040411735351747299230615776597356956641506445501689924551185923348003766988424170511157069264716719906995309826,
0.0253920653092620594557525897892240292875540475469487209362512822192154788532376645960457016338988332029324531233401833547954942765653767672102838323550828207273795044402516181251040411735351747299230615776597356956641506445501689924551185923348003766988424170511157069264716719906995309826,
0.0162743947309056706051705622063866181795429637952095664295931749613369651752917857651844425586692833071042366002861684552859449530958901379260437604156888337987656773068694383447504913457771896770689760342192010638946676879735404121702279005140285599424477022083127753774756520463311689155,
0.0162743947309056706051705622063866181795429637952095664295931749613369651752917857651844425586692833071042366002861684552859449530958901379260437604156888337987656773068694383447504913457771896770689760342192010638946676879735404121702279005140285599424477022083127753774756520463311689155,
0.0070186100094700966004070637388531825133772207289396032320082356192151241454178686953297376907573215077936155545790593837513204206518026084505878987243348925784479817181234617862457418214505322067610482902501455504204433524520665822704844582452877416001060465891907497519632353148380799619,
0.0070186100094700966004070637388531825133772207289396032320082356192151241454178686953297376907573215077936155545790593837513204206518026084505878987243348925784479817181234617862457418214505322067610482902501455504204433524520665822704844582452877416001060465891907497519632353148380799619
};
#endif
+986 -52
View File
File diff suppressed because it is too large Load Diff
+33 -3
View File
@@ -33,6 +33,7 @@ typedef union _GskCurve GskCurve;
typedef struct _GskLineCurve GskLineCurve;
typedef struct _GskQuadCurve GskQuadCurve;
typedef struct _GskCubicCurve GskCubicCurve;
typedef struct _GskConicCurve GskConicCurve;
struct _GskLineCurve
{
@@ -65,12 +66,28 @@ struct _GskCubicCurve
graphene_point_t coeffs[4];
};
struct _GskConicCurve
{
GskPathOperation op;
gboolean has_coefficients;
/* points[0], points[1], points[3] are the control points,
* points[2].x is the weight
*/
graphene_point_t points[4];
graphene_point_t num[3];
graphene_point_t denom[3];
};
union _GskCurve
{
GskPathOperation op;
GskLineCurve line;
GskQuadCurve quad;
GskCubicCurve cubic;
GskConicCurve conic;
};
typedef enum {
@@ -88,6 +105,7 @@ typedef gboolean (* GskCurveAddLineFunc) (const graphene_point_t *from,
typedef gboolean (* GskCurveAddCurveFunc) (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer user_data);
void gsk_curve_init (GskCurve *curve,
@@ -95,7 +113,8 @@ void gsk_curve_init (GskCurve
void gsk_curve_init_foreach (GskCurve *curve,
GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts);
gsize n_pts,
float weight);
void gsk_curve_print (const GskCurve *curve,
GString *string);
@@ -145,8 +164,9 @@ void gsk_curve_get_bounds (const GskCurve
void gsk_curve_get_tight_bounds (const GskCurve *curve,
GskBoundingBox *bounds);
void gsk_curve_get_derivative (const GskCurve *curve,
GskCurve *derivative);
void gsk_curve_get_derivative_at (const GskCurve *curve,
float t,
graphene_point_t *value);
int gsk_curve_get_crossing (const GskCurve *curve,
const graphene_point_t *point);
gboolean gsk_curve_get_closest_point (const GskCurve *curve,
@@ -154,6 +174,16 @@ gboolean gsk_curve_get_closest_point (const GskCurve
float threshold,
float *out_dist,
float *out_t);
float gsk_curve_get_length (const GskCurve *curve);
float gsk_curve_get_length_to (const GskCurve *curve,
float t);
float gsk_curve_at_length (const GskCurve *curve,
float distance,
float epsilon);
int gsk_curve_get_curvature_points (const GskCurve * curve,
float t[3]);
G_END_DECLS
+5 -1
View File
@@ -281,8 +281,11 @@ typedef enum {
* @GSK_PATH_CUBIC: A curve-to operation describing a cubic Bézier curve with 4
* points describing the start point, the two control points and the end point
* of the curve.
* @GSK_PATH_CONIC: A rational quadratic Bézier curve with 3 points describing
* the start point, control point and end point of the curve. A weight for the
* curve will be passed, too.
*
* Path operations are used to described segments of a `GskPath`.
* Path operations are used to describe the segments of a `GskPath`.
*
* More values may be added in the future.
*
@@ -294,6 +297,7 @@ typedef enum {
GSK_PATH_LINE,
GSK_PATH_QUAD,
GSK_PATH_CUBIC,
GSK_PATH_CONIC,
} GskPathOperation;
/**
+89 -29
View File
@@ -177,8 +177,9 @@ gsk_path_get_flags (const GskPath *self)
* Converts @self into a human-readable string representation suitable
* for printing.
*
* The string is compatible with
* [SVG path syntax](https://www.w3.org/TR/SVG11/paths.html#PathData).
* The string is compatible with (a superset of)
* [SVG path syntax](https://www.w3.org/TR/SVG11/paths.html#PathData),
* see [func@Gsk.Path.parse] for a summary of the syntax.
*
* Since: 4.14
*/
@@ -233,6 +234,7 @@ static gboolean
gsk_path_to_cairo_add_op (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer cr)
{
switch (op)
@@ -249,21 +251,12 @@ gsk_path_to_cairo_add_op (GskPathOperation op,
cairo_line_to (cr, pts[1].x, pts[1].y);
break;
case GSK_PATH_QUAD:
{
double x, y;
cairo_get_current_point (cr, &x, &y);
cairo_curve_to (cr,
1/3.f * x + 2/3.f * pts[1].x, 1/3.f * y + 2/3.f * pts[1].y,
2/3.f * pts[1].x + 1/3.f * pts[2].x, 2/3.f * pts[1].y + 1/3.f * pts[2].y,
pts[2].x, pts[2].y);
}
break;
case GSK_PATH_CUBIC:
cairo_curve_to (cr, pts[1].x, pts[1].y, pts[2].x, pts[2].y, pts[3].x, pts[3].y);
break;
case GSK_PATH_QUAD:
case GSK_PATH_CONIC:
default:
g_assert_not_reached ();
return FALSE;
@@ -375,7 +368,7 @@ gsk_path_is_closed (GskPath *self)
* If the path is empty, `FALSE` is returned and @bounds are set to
* graphene_rect_zero(). This is different from the case where the path
* is a single point at the origin, where the @bounds will also be set to
* the zero rectangle but 0 will be returned.
* the zero rectangle but `TRUE` will be returned.
*
* Returns: `TRUE` if the path has bounds, `FALSE` if the path is known
* to be empty and have no bounds.
@@ -428,6 +421,7 @@ gsk_path_get_bounds (GskPath *self,
*
* Returns: `TRUE` if the path has bounds, `FALSE` if the path is known
* to be empty and have no bounds.
*
* Since: 4.14
*/
gboolean
@@ -624,10 +618,17 @@ gsk_path_get_closest_point (GskPath *self,
*
* Calls @func for every operation of the path.
*
* Note that this only approximates @self, because paths can contain
* optimizations for various specialized contours, and depending on
* the @flags, the path may be decomposed into simpler curves than
* the ones that it contained originally.
* Note that this may only approximate @self, because paths can contain
* optimizations for various specialized contours, and depending on the
* @flags, the path may be decomposed into simpler curves than the ones
* that it contained originally.
*
* This function serves two purposes:
*
* - When the @flags allow everything, it provides access to the raw,
* unmodified data of the path.
* - When the @flags disallow certain operations, it provides
* an approximation of the path using just the allowed operations.
*
* Returns: `FALSE` if @func returned FALSE`, `TRUE` otherwise.
*
@@ -671,6 +672,7 @@ gsk_path_foreach_trampoline_add_line (const graphene_point_t *from,
return trampoline->func (GSK_PATH_LINE,
(graphene_point_t[2]) { *from, *to },
2,
0.f,
trampoline->user_data);
}
@@ -678,17 +680,19 @@ static gboolean
gsk_path_foreach_trampoline_add_curve (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer data)
{
GskPathForeachTrampoline *trampoline = data;
return trampoline->func (op, pts, n_pts, trampoline->user_data);
return trampoline->func (op, pts, n_pts, weight, trampoline->user_data);
}
static gboolean
gsk_path_foreach_trampoline (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer data)
{
GskPathForeachTrampoline *trampoline = data;
@@ -698,14 +702,14 @@ gsk_path_foreach_trampoline (GskPathOperation op,
case GSK_PATH_MOVE:
case GSK_PATH_CLOSE:
case GSK_PATH_LINE:
return trampoline->func (op, pts, n_pts, trampoline->user_data);
return trampoline->func (op, pts, n_pts, weight, trampoline->user_data);
case GSK_PATH_QUAD:
{
GskCurve curve;
if (trampoline->flags & GSK_PATH_FOREACH_ALLOW_QUAD)
return trampoline->func (op, pts, n_pts, trampoline->user_data);
return trampoline->func (op, pts, n_pts, weight, trampoline->user_data);
else if (trampoline->flags & GSK_PATH_FOREACH_ALLOW_CUBIC)
{
return trampoline->func (GSK_PATH_CUBIC,
@@ -718,6 +722,7 @@ gsk_path_foreach_trampoline (GskPathOperation op,
pts[2],
},
4,
weight,
trampoline->user_data);
}
@@ -733,10 +738,31 @@ gsk_path_foreach_trampoline (GskPathOperation op,
GskCurve curve;
if (trampoline->flags & GSK_PATH_FOREACH_ALLOW_CUBIC)
return trampoline->func (op, pts, n_pts, trampoline->user_data);
return trampoline->func (op, pts, n_pts, weight, trampoline->user_data);
gsk_curve_init (&curve, gsk_pathop_encode (GSK_PATH_CUBIC, pts));
if (trampoline->flags & GSK_PATH_FOREACH_ALLOW_QUAD)
if (trampoline->flags & (GSK_PATH_FOREACH_ALLOW_QUAD|GSK_PATH_FOREACH_ALLOW_CONIC))
return gsk_curve_decompose_curve (&curve,
trampoline->flags,
trampoline->tolerance,
gsk_path_foreach_trampoline_add_curve,
trampoline);
return gsk_curve_decompose (&curve,
trampoline->tolerance,
gsk_path_foreach_trampoline_add_line,
trampoline);
}
case GSK_PATH_CONIC:
{
GskCurve curve;
if (trampoline->flags & GSK_PATH_FOREACH_ALLOW_CONIC)
return trampoline->func (op, pts, n_pts, weight, trampoline->user_data);
gsk_curve_init (&curve, gsk_pathop_encode (GSK_PATH_CONIC, (graphene_point_t[4]) { pts[0], pts[1], { weight, 0.f }, pts[2] } ));
if (trampoline->flags & (GSK_PATH_FOREACH_ALLOW_QUAD|GSK_PATH_FOREACH_ALLOW_CUBIC))
return gsk_curve_decompose_curve (&curve,
trampoline->flags,
trampoline->tolerance,
@@ -755,8 +781,9 @@ gsk_path_foreach_trampoline (GskPathOperation op,
}
}
#define ALLOW_ANY (GSK_PATH_FOREACH_ALLOW_QUAD| \
GSK_PATH_FOREACH_ALLOW_CUBIC)
#define ALLOW_ANY (GSK_PATH_FOREACH_ALLOW_QUAD | \
GSK_PATH_FOREACH_ALLOW_CUBIC | \
GSK_PATH_FOREACH_ALLOW_CONIC)
gboolean
gsk_path_foreach_with_tolerance (GskPath *self,
@@ -914,7 +941,7 @@ parse_command (const char **p,
if (*cmd == 'X')
allowed = "mM";
else
allowed = "mMhHvVzZlLcCsStTqQaA";
allowed = "mMhHvVzZlLcCsStTqQaAoO";
skip_whitespace (p);
s = _strchr (allowed, **p);
@@ -934,7 +961,7 @@ parse_command (const char **p,
* This is a convenience function that constructs a `GskPath`
* from a serialized form.
*
* The string is expected to be in
* 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].
*
@@ -950,12 +977,14 @@ parse_command (const char **p,
* - `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.
*
* Returns: (nullable): a new `GskPath`, or `NULL`
* if @string could not be parsed
* 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
*/
@@ -1259,6 +1288,37 @@ gsk_path_parse (const char *string)
}
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':
{
+21 -9
View File
@@ -33,14 +33,15 @@ G_BEGIN_DECLS
* @GSK_PATH_FOREACH_ALLOW_ONLY_LINES: The default behavior, only allow lines.
* @GSK_PATH_FOREACH_ALLOW_QUAD: Allow emission of `GSK_PATH_QUAD` operations
* @GSK_PATH_FOREACH_ALLOW_CUBIC: Allow emission of `GSK_PATH_CUBIC` operations.
* @GSK_PATH_FOREACH_ALLOW_ANY: Allow emission of any kind of operation.
* @GSK_PATH_FOREACH_ALLOW_CONIC: Allow emission of `GSK_PATH_CONIC` operations.
*
* Flags that can be passed to gsk_path_foreach() to enable additional
* features.
* Flags that can be passed to gsk_path_foreach() to influence what
* kinds of operations the path is decomposed into.
*
* By default, [method@Gsk.Path.foreach] will only emit a path with all operations
* flattened to straight lines to allow for maximum compatibility. The only
* operations emitted will be `GSK_PATH_MOVE`, `GSK_PATH_LINE` and `GSK_PATH_CLOSE`.
* By default, [method@Gsk.Path.foreach] will only emit a path with all
* operations flattened to straight lines to allow for maximum compatibility.
* The only operations emitted will be `GSK_PATH_MOVE`, `GSK_PATH_LINE` and
* `GSK_PATH_CLOSE`.
*
* Since: 4.14
*/
@@ -49,24 +50,35 @@ typedef enum
GSK_PATH_FOREACH_ALLOW_ONLY_LINES = 0,
GSK_PATH_FOREACH_ALLOW_QUAD = (1 << 0),
GSK_PATH_FOREACH_ALLOW_CUBIC = (1 << 1),
GSK_PATH_FOREACH_ALLOW_CONIC = (1 << 2),
} GskPathForeachFlags;
/**
* GskPathForeachFunc:
* @op: The operation to perform
* @op: The operation
* @pts: The points of the operation
* @n_pts: The number of points
* @weight: The weight for conic curves, or unused if not a conic curve
* @user_data: The user data provided with the function
*
* Prototype of the callback to iterate throught the operations of
* Prototype of the callback to iterate through the operations of
* a path.
*
* Returns: %TRUE to continue evaluating the path, %FALSE to
* For each operation, the callback is given the @op itself, the points
* that the operation is applied to in @pts, and a @weight for conic
* curves. The @n_pts argument is somewhat redundant, since the number
* of points can be inferred from the operation.
*
* Each contour of the path starts with a @GSK_PATH_MOVE operation.
* Closed contours end with a @GSK_PATH_CLOSE operation.
*
* Returns: %TRUE to continue iterating the path, %FALSE to
* immediately abort and not call the function again.
*/
typedef gboolean (* GskPathForeachFunc) (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer user_data);
#define GSK_TYPE_PATH (gsk_path_get_type ())
+411 -63
View File
@@ -25,7 +25,6 @@
#include "gskpathprivate.h"
#include "gskcontourprivate.h"
#include "gsksplineprivate.h"
/**
* GskPathBuilder:
@@ -65,7 +64,7 @@
* [method@Gsk.PathBuilder.close] to close the path by connecting it
* back with a line to the starting point.
*
* This is similar for how paths are drawn in Cairo.
* This is similar to how paths are drawn in Cairo.
*
* Since: 4.14
*/
@@ -241,7 +240,7 @@ gsk_path_builder_unref (GskPathBuilder *self)
* @self: a `GskPathBuilder`
*
* Creates a new `GskPath` from the current state of the
* given builder, and frees the @builder instance.
* given builder, and unrefs the @builder instance.
*
* Returns: (transfer full): the newly created `GskPath`
* with all the contours added to the builder
@@ -311,12 +310,14 @@ gsk_path_builder_add_contour (GskPathBuilder *self,
* gsk_path_builder_get_current_point:
* @self: a `GskPathBuilder`
*
* Gets the current point. The current point is used for relative
* drawing commands and updated after every operation.
* Gets the current point.
*
* When the builder is created, the default current point is set to (0, 0).
* Note that this is different from cairo, which starts out without
* a current point.
* The current point is used for relative drawing commands and
* updated after every operation.
*
* When the builder is created, the default current point is set
* to `0, 0`. Note that this is different from cairo, which starts
* out without a current point.
*
* Returns: (transfer none): The current point
*
@@ -502,64 +503,46 @@ gsk_path_builder_add_rounded_rect (GskPathBuilder *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_svg_arc_to (self,
rect->corner[GSK_CORNER_TOP_RIGHT].width,
rect->corner[GSK_CORNER_TOP_RIGHT].height,
0, FALSE, TRUE,
rect->bounds.origin.x + rect->bounds.size.width,
rect->bounds.origin.y + rect->corner[GSK_CORNER_TOP_RIGHT].height);
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_svg_arc_to (self,
rect->corner[GSK_CORNER_BOTTOM_RIGHT].width,
rect->corner[GSK_CORNER_BOTTOM_RIGHT].height,
0, FALSE, TRUE,
rect->bounds.origin.x + rect->bounds.size.width - rect->corner[GSK_CORNER_BOTTOM_RIGHT].width,
rect->bounds.origin.y + rect->bounds.size.height);
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_svg_arc_to (self,
rect->corner[GSK_CORNER_BOTTOM_LEFT].width,
rect->corner[GSK_CORNER_BOTTOM_LEFT].height,
0, FALSE, TRUE,
rect->bounds.origin.x,
rect->bounds.origin.y + rect->bounds.size.height - rect->corner[GSK_CORNER_BOTTOM_LEFT].height);
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_svg_arc_to (self,
rect->corner[GSK_CORNER_TOP_LEFT].width,
rect->corner[GSK_CORNER_TOP_LEFT].height,
0, FALSE, TRUE,
rect->bounds.origin.x + rect->corner[GSK_CORNER_TOP_LEFT].width,
rect->bounds.origin.y);
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;
}
static gboolean
circle_contour_curve (const graphene_point_t pts[4],
gpointer data)
{
GskPathBuilder *self = data;
gsk_path_builder_cubic_to (self,
pts[1].x, pts[1].y,
pts[2].x, pts[2].y,
pts[3].x, pts[3].y);
return TRUE;
}
/**
* gsk_path_builder_add_circle:
* @self: a `GskPathBuilder`
@@ -586,11 +569,23 @@ gsk_path_builder_add_circle (GskPathBuilder *self,
current = self->current_point;
gsk_path_builder_move_to (self, center->x + radius, center->y);
gsk_spline_decompose_arc (center, radius,
GSK_PATH_TOLERANCE_DEFAULT,
0, 2 * M_PI,
circle_contour_curve, self);
// 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;
}
@@ -629,8 +624,8 @@ gsk_path_builder_move_to (GskPathBuilder *self,
* @x: x offset
* @y: y offset
*
* Starts a new contour by placing the pen at @x, @y relative to the current
* point.
* Starts a new contour by placing the pen at @x, @y
* relative to the current point.
*
* This is the relative version of [method@Gsk.PathBuilder.move_to].
*
@@ -689,8 +684,8 @@ gsk_path_builder_line_to (GskPathBuilder *self,
* @x: x offset
* @y: y offset
*
* Draws a line from the current point to a point offset to it by @x, @y
* and makes it the new current point.
* Draws a line from the current point to a point offset from it
* by @x, @y and makes it the new current point.
*
* This is the relative version of [method@Gsk.PathBuilder.line_to].
*
@@ -793,13 +788,13 @@ gsk_path_builder_rel_quad_to (GskPathBuilder *self,
* from the current point to @x3, @y3 with @x1, @y1 and @x2, @y2 as the control
* points.
*
* After this, @x3, @y3 will be the new current point.
*
* <picture>
* <source srcset="cubic-dark.png" media="(prefers-color-scheme: dark)">
* <img alt="Cubic To" src="cubic-light.png">
* </picture>
*
* After this, @x3, @y3 will be the new current point.
*
* Since: 4.14
*/
void
@@ -835,7 +830,9 @@ gsk_path_builder_cubic_to (GskPathBuilder *self,
*
* Adds a [cubic Bézier curve](https://en.wikipedia.org/wiki/B%C3%A9zier_curve)
* from the current point to @x3, @y3 with @x1, @y1 and @x2, @y2 as the control
* points. All coordinates are given relative to the current point.
* points.
*
* All coordinates are given relative to the current point.
*
* This is the relative version of [method@Gsk.PathBuilder.cubic_to].
*
@@ -861,6 +858,163 @@ gsk_path_builder_rel_cubic_to (GskPathBuilder *self,
self->current_point.y + y3);
}
/**
* gsk_path_builder_conic_to:
* @self: a `GskPathBuilder`
* @x1: x coordinate of control point
* @y1: y coordinate of control point
* @x2: x coordinate of the end of the curve
* @y2: y coordinate of the end of the curve
* @weight: weight of the control point, must be greater than zero
*
* Adds a [conic curve](https://en.wikipedia.org/wiki/Non-uniform_rational_B-spline)
* from the current point to @x2, @y2 with the given @weight and @x1, @y1 as the
* control point.
*
* The weight determines how strongly the curve is pulled towards the control point.
* A conic with weight 1 is identical to a quadratic Bézier curve with the same points.
*
* Conic curves can be used to draw ellipses and circles. They are also known as
* rational quadratic Bézier curves.
*
* After this, @x2, @y2 will be the new current point.
*
* <picture>
* <source srcset="conic-dark.png" media="(prefers-color-scheme: dark)">
* <img alt="Conic To" src="conic-light.png">
* </picture>
*
* Since: 4.14
*/
void
gsk_path_builder_conic_to (GskPathBuilder *self,
float x1,
float y1,
float x2,
float y2,
float weight)
{
g_return_if_fail (self != NULL);
g_return_if_fail (weight > 0);
self->flags &= ~GSK_PATH_FLAT;
gsk_path_builder_append_current (self,
GSK_PATH_CONIC,
3, (graphene_point_t[3]) {
GRAPHENE_POINT_INIT (x1, y1),
GRAPHENE_POINT_INIT (weight, 0),
GRAPHENE_POINT_INIT (x2, y2)
});
}
/**
* gsk_path_builder_rel_conic_to:
* @self: a `GskPathBuilder`
* @x1: x offset of control point
* @y1: y offset of control point
* @x2: x offset of the end of the curve
* @y2: y offset of the end of the curve
* @weight: weight of the curve, must be greater than zero
*
* Adds a [conic curve](https://en.wikipedia.org/wiki/Non-uniform_rational_B-spline)
* from the current point to @x2, @y2 with the given @weight and @x1, @y1 as the
* control point.
*
* All coordinates are given relative to the current point.
*
* This is the relative version of [method@Gsk.PathBuilder.conic_to].
*
* Since: 4.14
*/
void
gsk_path_builder_rel_conic_to (GskPathBuilder *self,
float x1,
float y1,
float x2,
float y2,
float weight)
{
g_return_if_fail (self != NULL);
g_return_if_fail (weight > 0);
gsk_path_builder_conic_to (self,
self->current_point.x + x1,
self->current_point.y + y1,
self->current_point.x + x2,
self->current_point.y + y2,
weight);
}
/**
* gsk_path_builder_arc_to:
* @self: a `GskPathBuilder`
* @x1: x coordinate of first control point
* @y1: y coordinate of first control point
* @x2: x coordinate of second control point
* @y2: y coordinate of second control point
*
* Adds an elliptical arc from the current point to @x3, @y3
* with @x1, @y1 determining the tangent directions.
*
* After this, @x3, @y3 will be the new current point.
*
* Note: Two points and their tangents do not determine
* a unique ellipse, so GSK just picks one. If you need more
* precise control, use [method@Gsk.PathBuilder.conic_to]
* or [method@Gsk.PathBuilder.svg_arc_to].
*
* <picture>
* <source srcset="arc-dark.png" media="(prefers-color-scheme: dark)">
* <img alt="Arc To" src="arc-light.png">
* </picture>
*
* Since: 4.14
*/
void
gsk_path_builder_arc_to (GskPathBuilder *self,
float x1,
float y1,
float x2,
float y2)
{
g_return_if_fail (self != NULL);
gsk_path_builder_conic_to (self, x1, y1, x2, y2, M_SQRT1_2);
}
/**
* gsk_path_builder_rel_arc_to:
* @self: a `GskPathBuilder`
* @x1: x coordinate of first control point
* @y1: y coordinate of first control point
* @x2: x coordinate of second control point
* @y2: y coordinate of second control point
*
* Adds an elliptical arc from the current point to @x3, @y3
* with @x1, @y1 determining the tangent directions.
*
* All coordinates are given relative to the current point.
*
* This is the relative version of [method@Gsk.PathBuilder.arc_to].
*
* Since: 4.14
*/
void
gsk_path_builder_rel_arc_to (GskPathBuilder *self,
float x1,
float y1,
float x2,
float y2)
{
g_return_if_fail (self != NULL);
gsk_path_builder_arc_to (self,
self->current_point.x + x1,
self->current_point.y + y1,
self->current_point.x + x2,
self->current_point.y + y2);
}
/**
* gsk_path_builder_close:
* @self: a `GskPathBuilder`
@@ -869,9 +1023,9 @@ gsk_path_builder_rel_cubic_to (GskPathBuilder *self,
*
* Note that this is different from calling [method@Gsk.PathBuilder.line_to]
* with the start point in that the contour will be closed. A closed
* contour behaves different from an open one when stroking its start
* and end point are considered connected, so they will be joined
* via the line join, and not ended with line caps.
* contour behaves differently from an open one. When stroking, its
* start and end point are considered connected, so they will be
* joined via the line join, and not ended with line caps.
*
* Since: 4.14
*/
@@ -938,6 +1092,27 @@ _sincos (double angle,
#endif
}
/**
* gsk_path_builder_svg_arc_to:
* @self: a `GskPathBuilder`
* @rx: X radius
* @ry: Y radius
* @x_axis_rotation: the rotation of the ellipsis
* @large_arc: whether to add the large arc
* @positive_sweep: whether to sweep in the positive direction
* @x: the X coordinate of the endpoint
* @y: the Y coordinate of the endpoint
*
* Implements arc-to according to the SVG spec.
*
* A convenience function that implements the
* [SVG arc_to](https://www.w3.org/TR/SVG11/paths.html#PathDataEllipticalArcCommands)
* functionality.
*
* After this, @x, @y will be the new current point.
*
* Since: 4.14
*/
void
gsk_path_builder_svg_arc_to (GskPathBuilder *self,
float rx,
@@ -970,6 +1145,8 @@ gsk_path_builder_svg_arc_to (GskPathBuilder *self,
double th_half;
double t;
g_return_if_fail (self != NULL);
if (self->points->len > 0)
{
current = &g_array_index (self->points, graphene_point_t, self->points->len - 1);
@@ -1069,13 +1246,184 @@ gsk_path_builder_svg_arc_to (GskPathBuilder *self,
}
}
/**
* gsk_path_builder_rel_svg_arc_to:
* @self: a `GskPathBuilder`
* @rx: X radius
* @ry: Y radius
* @x_axis_rotation: the rotation of the ellipsis
* @large_arc: whether to add the large arc
* @positive_sweep: whether to sweep in the positive direction
* @x: the X coordinate of the endpoint
* @y: the Y coordinate of the endpoint
*
* Implements arc-to according to the SVG spec.
*
* All coordinates are given relative to the current point.
*
* This is the relative version of [method@Gsk.PathBuilder.svg_arc_to].
*
* Since: 4.14
*/
void
gsk_path_builder_rel_svg_arc_to (GskPathBuilder *self,
float rx,
float ry,
float x_axis_rotation,
gboolean large_arc,
gboolean positive_sweep,
float x,
float y)
{
gsk_path_builder_svg_arc_to (self,
rx, ry,
x_axis_rotation,
large_arc,
positive_sweep,
self->current_point.x + x,
self->current_point.y + y);
}
/* Return the angle between t1 and t2 in radians, such that
* 0 means straight continuation
* < 0 means right turn
* > 0 means left turn
*/
static float
angle_between (const graphene_vec2_t *t1,
const graphene_vec2_t *t2)
{
float angle = atan2 (graphene_vec2_get_y (t2), graphene_vec2_get_x (t2))
- atan2 (graphene_vec2_get_y (t1), graphene_vec2_get_x (t1));
if (angle > M_PI)
angle -= 2 * M_PI;
if (angle < - M_PI)
angle += 2 * M_PI;
return angle;
}
#define RAD_TO_DEG(r) ((r)*180.f/M_PI)
#define DEG_TO_RAD(d) ((d)*M_PI/180.f)
static float
angle_between_points (const graphene_point_t *c,
const graphene_point_t *a,
const graphene_point_t *b)
{
graphene_vec2_t t1, t2;
graphene_vec2_init (&t1, a->x - c->x, a->y - c->y);
graphene_vec2_init (&t2, b->x - c->x, b->y - c->y);
return (float) RAD_TO_DEG (angle_between (&t1, &t2));
}
/**
* gsk_path_builder_html_arc_to:
* @self: a `GskPathBuilder`
* @x1: X coordinate of first control point
* @y1: Y coordinate of first control point
* @x2: X coordinate of second control point
* @y2: Y coordinate of second control point
* @radius: Radius of the circle
*
* Implements arc-to according to the HTML Canvas spec.
*
* A convenience function that implements the
* [HTML arc_to](https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-arcto-dev)
* functionality.
*
* After this, the current point will be the point where
* the circle with the given radius touches the line from
* @x1, @y1 to @x2, @y2.
*
* Since: 4.14
*/
void
gsk_path_builder_html_arc_to (GskPathBuilder *self,
float x1,
float y1,
float x2,
float y2,
float radius)
{
float angle, b;
graphene_vec2_t t;
graphene_point_t p, q;
g_return_if_fail (self != NULL);
g_return_if_fail (radius > 0);
angle = angle_between_points (&GRAPHENE_POINT_INIT (x1, y1),
&self->current_point,
&GRAPHENE_POINT_INIT (x2, y2));
if (fabsf (angle) < 3)
{
gsk_path_builder_line_to (self, x2, y2);
return;
}
b = radius / tanf (fabsf ((float) DEG_TO_RAD (angle / 2)));
graphene_vec2_init (&t, self->current_point.x - x1, self->current_point.y - y1);
graphene_vec2_normalize (&t, &t);
p.x = x1 + b * graphene_vec2_get_x (&t);
p.y = y1 + b * graphene_vec2_get_y (&t);
graphene_vec2_init (&t, x2 - x1, y2 - y1);
graphene_vec2_normalize (&t, &t);
q.x = x1 + b * graphene_vec2_get_x (&t);
q.y = y1 + b * graphene_vec2_get_y (&t);
gsk_path_builder_line_to (self, p.x, p.y);
gsk_path_builder_svg_arc_to (self, radius, radius, 0, FALSE, angle < 0, q.x, q.y);
}
/**
* gsk_path_builder_rel_html_arc_to:
* @self: a `GskPathBuilder`
* @x1: X coordinate of first control point
* @y1: Y coordinate of first control point
* @x2: X coordinate of second control point
* @y2: Y coordinate of second control point
* @radius: Radius of the circle
*
* Implements arc-to according to the HTML Canvas spec.
*
* All coordinates are given relative to the current point.
*
* This is the relative version of [method@Gsk.PathBuilder.html_arc_to].
*
* Since: 4.14
*/
void
gsk_path_builder_rel_html_arc_to (GskPathBuilder *self,
float x1,
float y1,
float x2,
float y2,
float radius)
{
gsk_path_builder_html_arc_to (self,
self->current_point.x + x1,
self->current_point.y + y1,
self->current_point.x + x2,
self->current_point.y + y2,
radius);
}
/**
* gsk_path_builder_add_layout:
* @self: a #GskPathBuilder
* @layout: the pango layout to add
*
* Adds the outlines for the glyphs in @layout to
* the builder.
* Adds the outlines for the glyphs in @layout to the builder.
*
* Since: 4.14
*/
+64
View File
@@ -120,6 +120,70 @@ void gsk_path_builder_rel_cubic_to (GskPathBuilder
float y2,
float x3,
float y3);
GDK_AVAILABLE_IN_4_14
void gsk_path_builder_conic_to (GskPathBuilder *self,
float x1,
float y1,
float x2,
float y2,
float weight);
GDK_AVAILABLE_IN_4_14
void gsk_path_builder_rel_conic_to (GskPathBuilder *self,
float x1,
float y1,
float x2,
float y2,
float weight);
GDK_AVAILABLE_IN_4_14
void gsk_path_builder_arc_to (GskPathBuilder *self,
float x1,
float y1,
float x2,
float y2);
GDK_AVAILABLE_IN_4_14
void gsk_path_builder_rel_arc_to (GskPathBuilder *self,
float x1,
float y1,
float x2,
float y2);
GDK_AVAILABLE_IN_4_14
void gsk_path_builder_svg_arc_to (GskPathBuilder *self,
float rx,
float ry,
float x_axis_rotation,
gboolean large_arc,
gboolean positive_sweep,
float x,
float y);
GDK_AVAILABLE_IN_4_14
void gsk_path_builder_rel_svg_arc_to (GskPathBuilder *self,
float rx,
float ry,
float x_axis_rotation,
gboolean large_arc,
gboolean positive_sweep,
float x,
float y);
GDK_AVAILABLE_IN_4_14
void gsk_path_builder_html_arc_to (GskPathBuilder *self,
float x1,
float y1,
float x2,
float y2,
float radius);
GDK_AVAILABLE_IN_4_14
void gsk_path_builder_rel_html_arc_to (GskPathBuilder *self,
float x1,
float y1,
float x2,
float y2,
float radius);
GDK_AVAILABLE_IN_4_14
void gsk_path_builder_close (GskPathBuilder *self);
+328
View File
@@ -0,0 +1,328 @@
/*
* 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 "gskpathmeasure.h"
#include "gskpathbuilder.h"
#include "gskpathpointprivate.h"
#include "gskpathprivate.h"
/**
* GskPathMeasure:
*
* `GskPathMeasure` is an object that allows measurements
* on `GskPath`s such as determining the length of the path.
*
* Many measuring operations require sampling the path length
* at intermediate points. Therefore, a `GskPathMeasure` has
* a tolerance that determines what precision is required
* for such approximations.
*
* A `GskPathMeasure` struct is a reference counted struct
* and should be treated as opaque.
*/
typedef struct _GskContourMeasure GskContourMeasure;
struct _GskContourMeasure
{
float length;
gpointer contour_data;
};
struct _GskPathMeasure
{
/*< private >*/
guint ref_count;
GskPath *path;
float tolerance;
float length;
gsize n_contours;
GskContourMeasure measures[];
};
G_DEFINE_BOXED_TYPE (GskPathMeasure, gsk_path_measure,
gsk_path_measure_ref,
gsk_path_measure_unref)
/**
* gsk_path_measure_new:
* @path: the path to measure
*
* Creates a measure object for the given @path with the
* default tolerance.
*
* Returns: a new `GskPathMeasure` representing @path
*
* Since: 4.14
*/
GskPathMeasure *
gsk_path_measure_new (GskPath *path)
{
return gsk_path_measure_new_with_tolerance (path, GSK_PATH_TOLERANCE_DEFAULT);
}
/**
* gsk_path_measure_new_with_tolerance:
* @path: the path to measure
* @tolerance: the tolerance for measuring operations
*
* Creates a measure object for the given @path and @tolerance.
*
* Returns: a new `GskPathMeasure` representing @path
*
* Since: 4.14
*/
GskPathMeasure *
gsk_path_measure_new_with_tolerance (GskPath *path,
float tolerance)
{
GskPathMeasure *self;
gsize i, n_contours;
g_return_val_if_fail (path != NULL, NULL);
g_return_val_if_fail (tolerance > 0, NULL);
n_contours = gsk_path_get_n_contours (path);
self = g_malloc0 (sizeof (GskPathMeasure) + n_contours * sizeof (GskContourMeasure));
self->ref_count = 1;
self->path = gsk_path_ref (path);
self->tolerance = tolerance;
self->n_contours = n_contours;
for (i = 0; i < n_contours; i++)
{
self->measures[i].contour_data = gsk_contour_init_measure (gsk_path_get_contour (path, i),
self->tolerance,
&self->measures[i].length);
self->length += self->measures[i].length;
}
return self;
}
/**
* gsk_path_measure_ref:
* @self: a `GskPathMeasure`
*
* Increases the reference count of a `GskPathMeasure` by one.
*
* Returns: the passed in `GskPathMeasure`.
*
* Since: 4.14
*/
GskPathMeasure *
gsk_path_measure_ref (GskPathMeasure *self)
{
g_return_val_if_fail (self != NULL, NULL);
self->ref_count++;
return self;
}
/**
* gsk_path_measure_unref:
* @self: a `GskPathMeasure`
*
* Decreases the reference count of a `GskPathMeasure` by one.
*
* If the resulting reference count is zero, frees the object.
*
* Since: 4.14
*/
void
gsk_path_measure_unref (GskPathMeasure *self)
{
gsize i;
g_return_if_fail (self != NULL);
g_return_if_fail (self->ref_count > 0);
self->ref_count--;
if (self->ref_count > 0)
return;
for (i = 0; i < self->n_contours; i++)
{
gsk_contour_free_measure (gsk_path_get_contour (self->path, i),
self->measures[i].contour_data);
}
gsk_path_unref (self->path);
g_free (self);
}
/**
* gsk_path_measure_get_path:
* @self: a `GskPathMeasure`
*
* Returns the path that the measure was created for.
*
* Returns: (transfer none): the path of @self
*
* Since: 4.14
*/
GskPath *
gsk_path_measure_get_path (GskPathMeasure *self)
{
return self->path;
}
/**
* gsk_path_measure_get_tolerance:
* @self: a `GskPathMeasure`
*
* Returns the tolerance that the measure was created with.
*
* Returns: the tolerance of @self
*
* Since: 4.14
*/
float
gsk_path_measure_get_tolerance (GskPathMeasure *self)
{
return self->tolerance;
}
/**
* gsk_path_measure_get_length:
* @self: a `GskPathMeasure`
*
* Gets the length of the path being measured.
*
* The length is cached, so this function does not do any work.
*
* Returns: The length of the path measured by @self
*
* Since: 4.14
*/
float
gsk_path_measure_get_length (GskPathMeasure *self)
{
g_return_val_if_fail (self != NULL, 0);
return self->length;
}
static float
gsk_path_measure_clamp_distance (GskPathMeasure *self,
float distance)
{
if (isnan (distance))
return 0;
return CLAMP (distance, 0, self->length);
}
/**
* gsk_path_measure_get_point:
* @self: a `GskPathMeasure`
* @distance: the distance
* @result: (out caller-allocates): return location for the result
*
* Sets @result to the point at the given distance into the path.
*
* An empty path has no points, so `FALSE` is returned in that case.
*
* Returns: `TRUE` if @result was set
*
* Since: 4.14
*/
gboolean
gsk_path_measure_get_point (GskPathMeasure *self,
float distance,
GskPathPoint *result)
{
GskRealPathPoint *res = (GskRealPathPoint *) result;
gsize i;
const GskContour *contour;
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (result != NULL, FALSE);
if (self->n_contours == 0)
return FALSE;
distance = gsk_path_measure_clamp_distance (self, distance);
for (i = 0; i < self->n_contours - 1; i++)
{
if (distance < self->measures[i].length)
break;
distance -= self->measures[i].length;
}
g_assert (0 <= i && i < self->n_contours);
distance = CLAMP (distance, 0, self->measures[i].length);
contour = gsk_path_get_contour (self->path, i);
gsk_contour_get_point (contour, self->measures[i].contour_data, distance, res);
res->contour = i;
return TRUE;
}
/**
* gsk_path_point_get_distance:
* @point: a `GskPathPoint on the path
* @measure: a `GskPathMeasure` for the path
*
* Returns the distance from the beginning of the path
* to @point.
*
* Returns: the distance of @point
*
* Since: 4.14
*/
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);
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,
measure->measures[i].contour_data);
contour_offset += measure->measures[i].length;
}
g_return_val_if_reached (0);
}
+62
View File
@@ -0,0 +1,62 @@
/*
* 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>
*/
#pragma once
#if !defined (__GSK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gsk/gsk.h> can be included directly."
#endif
#include <gsk/gskpath.h>
#include <gsk/gskpathpoint.h>
G_BEGIN_DECLS
#define GSK_TYPE_PATH_MEASURE (gsk_path_measure_get_type ())
GDK_AVAILABLE_IN_4_14
GType gsk_path_measure_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_4_14
GskPathMeasure * gsk_path_measure_new (GskPath *path);
GDK_AVAILABLE_IN_4_14
GskPathMeasure * gsk_path_measure_new_with_tolerance (GskPath *path,
float tolerance);
GDK_AVAILABLE_IN_4_14
GskPathMeasure * gsk_path_measure_ref (GskPathMeasure *self);
GDK_AVAILABLE_IN_4_14
void gsk_path_measure_unref (GskPathMeasure *self);
GDK_AVAILABLE_IN_4_14
GskPath * gsk_path_measure_get_path (GskPathMeasure *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
float gsk_path_measure_get_tolerance (GskPathMeasure *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
float gsk_path_measure_get_length (GskPathMeasure *self);
GDK_AVAILABLE_IN_4_14
gboolean gsk_path_measure_get_point (GskPathMeasure *self,
float distance,
GskPathPoint *result);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GskPathMeasure, gsk_path_measure_unref)
G_END_DECLS
+25 -4
View File
@@ -50,6 +50,13 @@ void gsk_path_builder_pathop_reverse_to (GskPathBuilder
/* IMPLEMENTATION */
/* Note:
*
* The weight of conics is encoded as p[2].x, and the endpoint is p[3].
* This is important, since contours store the points of adjacent
* operations overlapping, so we can't put the weight at the end.
*/
#define GSK_PATHOP_OPERATION_MASK (0x7)
static inline gskpathop
@@ -82,17 +89,23 @@ gsk_pathop_foreach (gskpathop pop,
switch (gsk_pathop_op (pop))
{
case GSK_PATH_MOVE:
return func (gsk_pathop_op (pop), gsk_pathop_points (pop), 1, user_data);
return func (gsk_pathop_op (pop), gsk_pathop_points (pop), 1, 0, user_data);
case GSK_PATH_CLOSE:
case GSK_PATH_LINE:
return func (gsk_pathop_op (pop), gsk_pathop_points (pop), 2, user_data);
return func (gsk_pathop_op (pop), gsk_pathop_points (pop), 2, 0, user_data);
case GSK_PATH_QUAD:
return func (gsk_pathop_op (pop), gsk_pathop_points (pop), 3, user_data);
return func (gsk_pathop_op (pop), gsk_pathop_points (pop), 3, 0, user_data);
case GSK_PATH_CUBIC:
return func (gsk_pathop_op (pop), gsk_pathop_points (pop), 4, user_data);
return func (gsk_pathop_op (pop), gsk_pathop_points (pop), 4, 0, user_data);
case GSK_PATH_CONIC:
{
const graphene_point_t *pts = gsk_pathop_points (pop);
return func (gsk_pathop_op (pop), (graphene_point_t[3]) { pts[0], pts[1], pts[3] }, 3, pts[2].x, user_data);
}
default:
g_assert_not_reached ();
@@ -128,6 +141,10 @@ gsk_path_builder_pathop_to (GskPathBuilder *builder,
gsk_path_builder_cubic_to (builder, pts[1].x, pts[1].y, pts[2].x, pts[2].y, pts[3].x, pts[3].y);
break;
case GSK_PATH_CONIC:
gsk_path_builder_conic_to (builder, pts[1].x, pts[1].y, pts[3].x, pts[3].y, pts[2].x);
break;
default:
g_assert_not_reached ();
break;
@@ -162,6 +179,10 @@ gsk_path_builder_pathop_reverse_to (GskPathBuilder *builder,
gsk_path_builder_cubic_to (builder, pts[2].x, pts[2].y, pts[1].x, pts[1].y, pts[0].x, pts[0].y);
break;
case GSK_PATH_CONIC:
gsk_path_builder_conic_to (builder, pts[1].x, pts[1].y, pts[0].x, pts[0].y, pts[2].x);
break;
default:
g_assert_not_reached ();
break;
+28 -7
View File
@@ -34,10 +34,12 @@
*
* `GskPathPoint` is an opaque type representing a point on a path.
*
* It can be queried for properties of the path at that point, such as its
* tangent or its curvature.
* It can be queried for properties of the path at that point, such as
* its tangent or its curvature.
*
* To obtain a `GskPathPoint`, use [method@Gsk.Path.get_closest_point].
* To obtain a `GskPathPoint`, use [method@Gsk.Path.get_closest_point],
* [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
@@ -85,6 +87,8 @@ gsk_path_point_free (GskPathPoint *point)
* same location.
*
* Return: `TRUE` if @point1 and @point2 are equal
*
* Since: 4.14
*/
gboolean
gsk_path_point_equal (const GskPathPoint *point1,
@@ -114,6 +118,8 @@ gsk_path_point_equal (const GskPathPoint *point1,
* Returns: -1 if @point1 is before @point2,
* 1 if @point1 is after @point2,
* 0 if they are equal
*
* Since: 4.14
*/
int
gsk_path_point_compare (const GskPathPoint *point1,
@@ -219,7 +225,8 @@ gsk_path_point_get_tangent (const GskPathPoint *point,
*
* This is a convenience variant of [method@Gsk.PathPoint.get_tangent]
* that returns the angle between the tangent and the X axis. The angle
* can e.g. be used in [method@Gtk.Snapshot.rotate].
* can e.g. be used in
* [gtk_snapshot_rotate()](../gtk4/method.Snapshot.rotate.html).
*
* Returns: the angle between the tangent and the X axis, in degrees
*
@@ -247,16 +254,29 @@ gsk_path_point_get_rotation (const GskPathPoint *point,
* gsk_path_point_get_curvature:
* @point: a `GskPathPoint`
* @path: the path that @point is on
* @direction: the direction for which to return the curvature
* @center: (out caller-allocates) (nullable): Return location for
* the center of the osculating circle
*
* Calculates the curvature of the path at the point.
*
* Optionally, returns the center of the osculating circle as well.
* The curvature is the inverse of the radius of the osculating circle.
*
* If the curvature is infinite (at line segments), zero is returned,
* and @center is not modified.
* Lines have a curvature of zero (indicating an osculating circle of
* infinite radius. In this case, the @center is not modified.
*
* 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,
* and the (limit of) the curvature of the path coming out of it.
* The @direction argument lets you choose which one to get.
*
* <picture>
* <source srcset="curvature-dark.png" media="(prefers-color-scheme: dark)">
* <img alt="Osculating circle" src="curvature-light.png">
* </picture>
* Returns: The curvature of the path at the given point
*
* Since: 4.14
@@ -264,6 +284,7 @@ gsk_path_point_get_rotation (const GskPathPoint *point,
float
gsk_path_point_get_curvature (const GskPathPoint *point,
GskPath *path,
GskPathDirection direction,
graphene_point_t *center)
{
GskRealPathPoint *self = (GskRealPathPoint *) point;
@@ -274,5 +295,5 @@ gsk_path_point_get_curvature (const GskPathPoint *point,
g_return_val_if_fail (self->contour < gsk_path_get_n_contours (path), 0);
contour = gsk_path_get_contour (path, self->contour);
return gsk_contour_get_curvature (contour, self, center);
return gsk_contour_get_curvature (contour, self, direction, center);
}
+4
View File
@@ -75,7 +75,11 @@ float gsk_path_point_get_rotation (const GskPathPoint *poin
GDK_AVAILABLE_IN_4_14
float gsk_path_point_get_curvature (const GskPathPoint *point,
GskPath *path,
GskPathDirection direction,
graphene_point_t *center);
GDK_AVAILABLE_IN_4_14
float gsk_path_point_get_distance (const GskPathPoint *point,
GskPathMeasure *measure);
G_END_DECLS
-10
View File
@@ -56,15 +56,5 @@ gboolean gsk_path_foreach_with_tolerance (GskPath
void gsk_path_builder_add_contour (GskPathBuilder *builder,
GskContour *contour);
void gsk_path_builder_svg_arc_to (GskPathBuilder *builder,
float rx,
float ry,
float x_axis_rotation,
gboolean large_arc,
gboolean positive_sweep,
float x,
float y);
G_END_DECLS
+10
View File
@@ -26,3 +26,13 @@ gsk_rect_intersects (const graphene_rect_t *r1,
return TRUE;
}
static inline void
gsk_rect_to_float (const graphene_rect_t *rect,
float values[4])
{
values[0] = rect->origin.x;
values[1] = rect->origin.y;
values[2] = rect->size.width;
values[3] = rect->size.height;
}
+111 -6
View File
@@ -1172,10 +1172,16 @@ create_default_texture (void)
return texture;
}
static GskRenderNode *
create_default_render_node_with_bounds (const graphene_rect_t *rect)
{
return gsk_color_node_new (&GDK_RGBA("FF00CC"), rect);
}
static GskRenderNode *
create_default_render_node (void)
{
return gsk_color_node_new (&GDK_RGBA("FF00CC"), &GRAPHENE_RECT_INIT (0, 0, 50, 50));
return create_default_render_node_with_bounds (&GRAPHENE_RECT_INIT (0, 0, 50, 50));
}
static GskPath *
@@ -2152,6 +2158,52 @@ clear_path (gpointer inout_path)
g_clear_pointer ((GskPath **) inout_path, gsk_path_unref);
}
static gboolean
parse_dash (GtkCssParser *parser,
Context *context,
gpointer out_dash)
{
GArray *dash;
double d;
/* because CSS does this, too */
if (gtk_css_parser_try_ident (parser, "none"))
{
*((GArray **) out_dash) = NULL;
return TRUE;
}
dash = g_array_new (FALSE, FALSE, sizeof (float));
while (gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_SIGNLESS_NUMBER) ||
gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_SIGNLESS_INTEGER))
{
if (!gtk_css_parser_consume_number (parser, &d))
{
g_array_free (dash, TRUE);
return FALSE;
}
g_array_append_vals (dash, (float[1]) { d }, 1);
}
if (dash->len == 0)
{
gtk_css_parser_error_syntax (parser, "Empty dash array");
g_array_free (dash, TRUE);
return FALSE;
}
*((GArray **) out_dash) = dash;
return TRUE;
}
static void
clear_dash (gpointer inout_array)
{
g_clear_pointer ((GArray **) inout_array, g_array_unref);
}
static gboolean
parse_enum (GtkCssParser *parser,
GType type,
@@ -2208,10 +2260,14 @@ parse_fill_node (GtkCssParser *parser,
GskRenderNode *result;
parse_declarations (parser, context, declarations, G_N_ELEMENTS (declarations));
if (child == NULL)
child = create_default_render_node ();
if (path == NULL)
path = create_default_path ();
if (child == NULL)
{
graphene_rect_t bounds;
gsk_path_get_bounds (path, &bounds);
child = create_default_render_node_with_bounds (&bounds);
}
result = gsk_fill_node_new (child, path, rule);
@@ -2248,6 +2304,8 @@ parse_stroke_node (GtkCssParser *parser,
int line_cap = GSK_LINE_CAP_BUTT;
int line_join = GSK_LINE_JOIN_MITER;
double miter_limit = 4.0;
GArray *dash = NULL;
double dash_offset = 0.0;
GskStroke *stroke;
const Declaration declarations[] = {
@@ -2256,13 +2314,13 @@ parse_stroke_node (GtkCssParser *parser,
{ "line-width", parse_positive_double, NULL, &line_width },
{ "line-cap", parse_line_cap, NULL, &line_cap },
{ "line-join", parse_line_join, NULL, &line_join },
{ "miter-limit", parse_positive_double, NULL, &miter_limit }
{ "miter-limit", parse_positive_double, NULL, &miter_limit },
{ "dash", parse_dash, clear_dash, &dash },
{ "dash-offset", parse_double, NULL, &dash_offset}
};
GskRenderNode *result;
parse_declarations (parser, context, declarations, G_N_ELEMENTS (declarations));
if (child == NULL)
child = create_default_render_node ();
if (path == NULL)
path = create_default_path ();
@@ -2270,6 +2328,19 @@ parse_stroke_node (GtkCssParser *parser,
gsk_stroke_set_line_cap (stroke, line_cap);
gsk_stroke_set_line_join (stroke, line_join);
gsk_stroke_set_miter_limit (stroke, miter_limit);
if (dash)
{
gsk_stroke_set_dash (stroke, (float *) dash->data, dash->len);
g_array_free (dash, TRUE);
}
gsk_stroke_set_dash_offset (stroke, dash_offset);
if (child == NULL)
{
graphene_rect_t bounds;
gsk_path_get_stroke_bounds (path, stroke, &bounds);
child = create_default_render_node_with_bounds (&bounds);
}
result = gsk_stroke_node_new (child, path, stroke);
@@ -3280,6 +3351,34 @@ append_path_param (Printer *p,
g_free (str);
}
static void
append_dash_param (Printer *p,
const char *param_name,
const float *dash,
gsize n_dash)
{
_indent (p);
g_string_append (p->str, "dash: ");
if (n_dash == 0)
{
g_string_append (p->str, "none");
}
else
{
gsize i;
string_append_double (p->str, dash[0]);
for (i = 1; i < n_dash; i++)
{
g_string_append_c (p->str, ' ');
string_append_double (p->str, dash[i]);
}
}
g_string_append (p->str, ";\n");
}
static void
render_node_print (Printer *p,
GskRenderNode *node)
@@ -3468,6 +3567,8 @@ render_node_print (Printer *p,
case GSK_STROKE_NODE:
{
const GskStroke *stroke;
const float *dash;
gsize n_dash;
start_node (p, "stroke", node_name);
@@ -3479,6 +3580,10 @@ render_node_print (Printer *p,
append_enum_param (p, "line-cap", GSK_TYPE_LINE_CAP, gsk_stroke_get_line_cap (stroke));
append_enum_param (p, "line-join", GSK_TYPE_LINE_JOIN, gsk_stroke_get_line_join (stroke));
append_float_param (p, "miter-limit", gsk_stroke_get_miter_limit (stroke), 4.0f);
dash = gsk_stroke_get_dash (stroke, &n_dash);
if (dash)
append_dash_param (p, "dash", dash, n_dash);
append_float_param (p, "dash-offset", gsk_stroke_get_dash_offset (stroke), 0.0f);
end_node (p);
}
+1 -1
View File
@@ -368,7 +368,7 @@ gsk_stroke_get_miter_limit (const GskStroke *self)
* gsk_stroke_set_dash:
* @self: a `GskStroke`
* @dash: (array length=n_dash) (transfer none) (nullable):
* the array of dashes
* the array of dashes
* @n_dash: number of elements in @dash
*
* Sets the dash pattern to use by this stroke.
+2 -1
View File
@@ -857,7 +857,8 @@ normalize_angle (float angle)
* @next: (nullable) (transfer full): the next transform
* @angle: the rotation angle, in degrees (clockwise)
*
* Rotates @next @angle degrees in 2D - or in 3D-speak, around the z axis.
* Rotates @next @angle degrees in 2D - or in 3D-speak, around the Z axis.
* The rotation happens around the origin point of (0, 0).
*
* Returns: (nullable): The new transform
*/
+1
View File
@@ -27,6 +27,7 @@
typedef struct _GskPath GskPath;
typedef struct _GskPathBuilder GskPathBuilder;
typedef struct _GskPathMeasure GskPathMeasure;
typedef struct _GskPathPoint GskPathPoint;
typedef struct _GskRenderer GskRenderer;
typedef struct _GskRenderNode GskRenderNode;
+3 -6
View File
@@ -28,6 +28,7 @@ gsk_public_sources = files([
'gskglshader.c',
'gskpath.c',
'gskpathbuilder.c',
'gskpathmeasure.c',
'gskpathpoint.c',
'gskrenderer.c',
'gskrendernode.c',
@@ -75,6 +76,7 @@ gsk_public_headers = files([
'gskglshader.h',
'gskpath.h',
'gskpathbuilder.h',
'gskpathmeasure.h',
'gskpathpoint.h',
'gskrenderer.h',
'gskrendernode.h',
@@ -108,10 +110,6 @@ if have_vulkan
endif
gsk_private_vulkan_shaders = []
# This is an odd split because we use configure_file() below to workaround
# a limitation in meson preventing using custom_target() with gnome.compile_resources()
# and that requires file paths, but we also need to have dependencies during development
# on constantly regenerated files.
gsk_private_vulkan_compiled_shaders = []
gsk_private_vulkan_compiled_shaders_deps = []
gsk_private_vulkan_shader_headers = []
@@ -159,7 +157,7 @@ if get_variable('broadway_enabled')
])
endif
gsk_resources_xml = configure_file(output: 'gsk.resources.xml',
gsk_resources_xml = custom_target(output: 'gsk.resources.xml',
input: 'gen-gsk-gresources-xml.py',
command: [
find_program('gen-gsk-gresources-xml.py'),
@@ -195,7 +193,6 @@ gsk_deps = [
pango_dep,
cairo_dep,
cairo_csi_dep,
pixbuf_dep,
libgdk_dep,
]
+5 -5
View File
@@ -43,11 +43,11 @@ gsk_vulkan_blend_mode_op_collect_vertex_data (GskVulkanOp *op,
GskVulkanBlendModeOp *self = (GskVulkanBlendModeOp *) op;
GskVulkanBlendModeInstance *instance = (GskVulkanBlendModeInstance *) (data + ((GskVulkanShaderOp *) op)->vertex_offset);
gsk_vulkan_rect_to_float (&self->bounds, instance->rect);
gsk_vulkan_rect_to_float (&self->top.rect, instance->top_rect);
gsk_vulkan_rect_to_float (&self->bottom.rect, instance->bottom_rect);
gsk_vulkan_rect_to_float (&self->top.tex_rect, instance->top_tex_rect);
gsk_vulkan_rect_to_float (&self->bottom.tex_rect, instance->bottom_tex_rect);
gsk_rect_to_float (&self->bounds, instance->rect);
gsk_rect_to_float (&self->top.rect, instance->top_rect);
gsk_rect_to_float (&self->bottom.rect, instance->bottom_rect);
gsk_rect_to_float (&self->top.tex_rect, instance->top_tex_rect);
gsk_rect_to_float (&self->bottom.tex_rect, instance->bottom_tex_rect);
instance->top_tex_id = self->top.image_descriptor;
instance->bottom_tex_id = self->bottom.image_descriptor;
+2 -2
View File
@@ -41,8 +41,8 @@ gsk_vulkan_blur_op_collect_vertex_data (GskVulkanOp *op,
GskVulkanBlurOp *self = (GskVulkanBlurOp *) op;
GskVulkanBlurInstance *instance = (GskVulkanBlurInstance *) (data + ((GskVulkanShaderOp *) op)->vertex_offset);
gsk_vulkan_rect_to_float (&self->rect, instance->rect);
gsk_vulkan_rect_to_float (&self->tex_rect, instance->tex_rect);
gsk_rect_to_float (&self->rect, instance->rect);
gsk_rect_to_float (&self->tex_rect, instance->tex_rect);
instance->tex_id = self->image_descriptor;
instance->radius = self->radius;
}
+5 -5
View File
@@ -43,11 +43,11 @@ gsk_vulkan_cross_fade_op_collect_vertex_data (GskVulkanOp *op,
GskVulkanCrossFadeOp *self = (GskVulkanCrossFadeOp *) op;
GskVulkanCrossFadeInstance *instance = (GskVulkanCrossFadeInstance *) (data + ((GskVulkanShaderOp *) op)->vertex_offset);
gsk_vulkan_rect_to_float (&self->bounds, instance->rect);
gsk_vulkan_rect_to_float (&self->start.rect, instance->start_rect);
gsk_vulkan_rect_to_float (&self->end.rect, instance->end_rect);
gsk_vulkan_rect_to_float (&self->start.tex_rect, instance->start_tex_rect);
gsk_vulkan_rect_to_float (&self->end.tex_rect, instance->end_tex_rect);
gsk_rect_to_float (&self->bounds, instance->rect);
gsk_rect_to_float (&self->start.rect, instance->start_rect);
gsk_rect_to_float (&self->end.rect, instance->end_rect);
gsk_rect_to_float (&self->start.tex_rect, instance->start_tex_rect);
gsk_rect_to_float (&self->end.tex_rect, instance->end_tex_rect);
instance->start_tex_id = self->start.image_descriptor;
instance->end_tex_id = self->end.image_descriptor;
+2 -2
View File
@@ -42,8 +42,8 @@ gsk_vulkan_glyph_op_collect_vertex_data (GskVulkanOp *op,
GskVulkanGlyphOp *self = (GskVulkanGlyphOp *) op;
GskVulkanGlyphInstance *instance = (GskVulkanGlyphInstance *) (data + ((GskVulkanShaderOp *) op)->vertex_offset);
gsk_vulkan_rect_to_float (&self->rect, instance->rect);
gsk_vulkan_rect_to_float (&self->tex_rect, instance->tex_rect);
gsk_rect_to_float (&self->rect, instance->rect);
gsk_rect_to_float (&self->tex_rect, instance->tex_rect);
instance->tex_id = self->image_descriptor;
gsk_vulkan_rgba_to_float (&self->color, instance->color);
}
+1 -1
View File
@@ -51,7 +51,7 @@ gsk_vulkan_linear_gradient_op_collect_vertex_data (GskVulkanOp *op,
GskVulkanLinearGradientOp *self = (GskVulkanLinearGradientOp *) op;
GskVulkanLinearInstance *instance = (GskVulkanLinearInstance *) (data + ((GskVulkanShaderOp *) op)->vertex_offset);
gsk_vulkan_rect_to_float (&self->rect, instance->rect);
gsk_rect_to_float (&self->rect, instance->rect);
gsk_vulkan_point_to_float (&self->start, instance->start);
gsk_vulkan_point_to_float (&self->end, instance->end);
instance->repeating = self->repeating;
+4 -4
View File
@@ -60,11 +60,11 @@ gsk_vulkan_mask_op_collect_vertex_data (GskVulkanOp *op,
GskVulkanMaskOp *self = (GskVulkanMaskOp *) op;
GskVulkanMaskInstance *instance = (GskVulkanMaskInstance *) (data + ((GskVulkanShaderOp *) op)->vertex_offset);
gsk_vulkan_rect_to_float (&self->source.rect, instance->source_rect);
gsk_vulkan_rect_to_float (&self->source.tex_rect, instance->source_tex_rect);
gsk_rect_to_float (&self->source.rect, instance->source_rect);
gsk_rect_to_float (&self->source.tex_rect, instance->source_tex_rect);
instance->source_id = self->source.image_descriptor;
gsk_vulkan_rect_to_float (&self->mask.rect, instance->mask_rect);
gsk_vulkan_rect_to_float (&self->mask.tex_rect, instance->mask_tex_rect);
gsk_rect_to_float (&self->mask.rect, instance->mask_rect);
gsk_rect_to_float (&self->mask.tex_rect, instance->mask_tex_rect);
instance->mask_id = self->mask.image_descriptor;
instance->mask_mode = self->mask_mode;
}
+1 -10
View File
@@ -2,6 +2,7 @@
#include "gskdebugprivate.h"
#include "gskrectprivate.h"
#include "gskroundedrectprivate.h"
#include <gdk/gdk.h>
@@ -37,16 +38,6 @@ gsk_vulkan_normalize_tex_coords (graphene_rect_t *tex_coords,
rect->size.height / tex->size.height);
}
static inline void
gsk_vulkan_rect_to_float (const graphene_rect_t *rect,
float values[4])
{
values[0] = rect->origin.x;
values[1] = rect->origin.y;
values[2] = rect->size.width;
values[3] = rect->size.height;
}
static inline void
gsk_vulkan_rgba_to_float (const GdkRGBA *rgba,
float values[4])
+5 -3
View File
@@ -1,9 +1,11 @@
#extension GL_EXT_nonuniform_qualifier : enable
layout(set = 0, binding = 0) uniform sampler2D textures[50000];
layout(set = 1, binding = 0) readonly buffer FloatBuffers {
float floats[];
} buffers[50000];
#define get_sampler(id) textures[id]
#define get_buffer(id) buffers[id]
#define get_float(id) get_buffer(0).floats[id]
#define get_sampler(id) textures[nonuniformEXT (id)]
#define get_buffer(id) buffers[nonuniformEXT (id)]
#define get_float(id) get_buffer(0).floats[nonuniformEXT (id)]
+7 -7
View File
@@ -93,12 +93,12 @@ foreach shader: gsk_private_vulkan_shaders
endforeach
foreach shader: gsk_private_vulkan_vertex_shaders
shader_header = configure_file(output: '@0@.h'.format(shader),
input: shader,
command: [
find_program('generate-header.py'),
'@INPUT@',
],
capture: true)
shader_header = custom_target(output: '@0@.h'.format(shader),
input: shader,
command: [
find_program('generate-header.py'),
'@INPUT@',
],
capture: true)
gsk_private_vulkan_shader_headers += shader_header
endforeach
+1 -1
View File
@@ -395,7 +395,7 @@ gtk_font_dialog_button_class_init (GtkFontDialogButtonClass *class)
g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
/**
* FontDialogButton::activate:
* GtkFontDialogButton::activate:
* @widget: The object which received the signal
*
* Emitted when the font dialog button is activated.
+16 -16
View File
@@ -1353,35 +1353,35 @@ gtk_menu_button_get_use_underline (GtkMenuButton *menu_button)
}
static GList *
get_menu_bars (GtkWindow *window)
get_menu_bars (GtkWidget *toplevel)
{
return g_object_get_data (G_OBJECT (window), "gtk-menu-bar-list");
return g_object_get_data (G_OBJECT (toplevel), "gtk-menu-bar-list");
}
static void
set_menu_bars (GtkWindow *window,
set_menu_bars (GtkWidget *toplevel,
GList *menubars)
{
g_object_set_data (G_OBJECT (window), I_("gtk-menu-bar-list"), menubars);
g_object_set_data (G_OBJECT (toplevel), I_("gtk-menu-bar-list"), menubars);
}
static void
add_to_window (GtkWindow *window,
GtkMenuButton *button)
add_to_toplevel (GtkWidget *toplevel,
GtkMenuButton *button)
{
GList *menubars = get_menu_bars (window);
GList *menubars = get_menu_bars (toplevel);
set_menu_bars (window, g_list_prepend (menubars, button));
set_menu_bars (toplevel, g_list_prepend (menubars, button));
}
static void
remove_from_window (GtkWindow *window,
GtkMenuButton *button)
remove_from_toplevel (GtkWidget *toplevel,
GtkMenuButton *button)
{
GList *menubars = get_menu_bars (window);
GList *menubars = get_menu_bars (toplevel);
menubars = g_list_remove (menubars, button);
set_menu_bars (window, menubars);
set_menu_bars (toplevel, menubars);
}
static void
@@ -1394,7 +1394,7 @@ gtk_menu_button_root (GtkWidget *widget)
if (button->primary)
{
GtkWidget *toplevel = GTK_WIDGET (gtk_widget_get_root (widget));
add_to_window (GTK_WINDOW (toplevel), button);
add_to_toplevel (toplevel, button);
}
}
@@ -1404,7 +1404,7 @@ gtk_menu_button_unroot (GtkWidget *widget)
GtkWidget *toplevel;
toplevel = GTK_WIDGET (gtk_widget_get_root (widget));
remove_from_window (GTK_WINDOW (toplevel), GTK_MENU_BUTTON (widget));
remove_from_toplevel (toplevel, GTK_MENU_BUTTON (widget));
GTK_WIDGET_CLASS (gtk_menu_button_parent_class)->unroot (widget);
}
@@ -1437,9 +1437,9 @@ gtk_menu_button_set_primary (GtkMenuButton *menu_button,
if (toplevel)
{
if (menu_button->primary)
add_to_window (GTK_WINDOW (toplevel), menu_button);
add_to_toplevel (GTK_WIDGET (toplevel), menu_button);
else
remove_from_window (GTK_WINDOW (toplevel), menu_button);
remove_from_toplevel (GTK_WIDGET (toplevel), menu_button);
}
g_object_notify_by_pspec (G_OBJECT (menu_button), menu_button_props[PROP_PRIMARY]);
+3 -1
View File
@@ -5409,7 +5409,9 @@ gtk_notebook_real_switch_page (GtkNotebook *notebook,
if (notebook->cur_page)
{
GtkRoot *root = gtk_widget_get_root (GTK_WIDGET (notebook));
GtkWidget *focus = gtk_root_get_focus (root);
GtkWidget *focus = NULL;
if (root)
focus = gtk_root_get_focus (root);
if (focus)
child_has_focus = gtk_widget_is_ancestor (focus, notebook->cur_page->child);
gtk_widget_unset_state_flags (notebook->cur_page->tab_widget, GTK_STATE_FLAG_CHECKED);
+1
View File
@@ -29,6 +29,7 @@
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gtk/gtkborder.h>
#include <gtk/gtkwidget.h>
+37 -3
View File
@@ -40,6 +40,14 @@
* depending on the application context.
*
* This widget is only meant to be used with [class@Gtk.ShortcutsWindow].
*
* The recommended way to construct a `GtkShortcutsGroup` is with
* [class@Gtk.Builder], by using the `<child>` tag to populate a
* `GtkShortcutsGroup` with one or more [class@Gtk.ShortcutsShortcut]
* instances.
*
* If you need to add a shortcut programmatically, use
* [method@Gtk.ShortcutsGroup.add_shortcut].
*/
struct _GtkShortcutsGroup
@@ -152,9 +160,8 @@ gtk_shortcuts_group_buildable_add_child (GtkBuildable *buildable,
{
if (GTK_IS_SHORTCUTS_SHORTCUT (child))
{
gtk_box_append (GTK_BOX (buildable), GTK_WIDGET (child));
gtk_shortcuts_group_apply_accel_size_group (GTK_SHORTCUTS_GROUP (buildable), GTK_WIDGET (child));
gtk_shortcuts_group_apply_title_size_group (GTK_SHORTCUTS_GROUP (buildable), GTK_WIDGET (child));
gtk_shortcuts_group_add_shortcut (GTK_SHORTCUTS_GROUP (buildable),
GTK_SHORTCUTS_SHORTCUT (child));
}
else
parent_buildable_iface->add_child (buildable, builder, child, type);
@@ -361,3 +368,30 @@ gtk_shortcuts_group_init (GtkShortcutsGroup *self)
GTK_ACCESSIBLE_RELATION_LABELLED_BY, self->title, NULL,
-1);
}
/**
* gtk_shortcuts_group_add_shortcut:
* @self: a `GtkShortcutsGroup`
* @shortcut: the `GtkShortcutsShortcut` to add
*
* Adds a shortcut to the shortcuts group.
*
* This is the programmatic equivalent to using [class@Gtk.Builder] and a
* `<child>` tag to add the child. Adding children with other API is not
* appropriate as `GtkShortcutsGroup` manages its children internally.
*
* Since: 4.14
*/
void
gtk_shortcuts_group_add_shortcut (GtkShortcutsGroup *self,
GtkShortcutsShortcut *shortcut)
{
g_return_if_fail (GTK_IS_SHORTCUTS_GROUP (self));
g_return_if_fail (GTK_IS_SHORTCUTS_SHORTCUT (shortcut));
g_return_if_fail (gtk_widget_get_parent (GTK_WIDGET (shortcut)) == NULL);
GtkWidget *widget = GTK_WIDGET (shortcut);
gtk_box_append (GTK_BOX (self), widget);
gtk_shortcuts_group_apply_accel_size_group (self, widget);
gtk_shortcuts_group_apply_title_size_group (self, widget);
}
+5 -1
View File
@@ -23,6 +23,7 @@
#endif
#include <gdk/gdk.h>
#include <gtk/gtkshortcutsshortcut.h>
G_BEGIN_DECLS
@@ -30,12 +31,15 @@ G_BEGIN_DECLS
#define GTK_SHORTCUTS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SHORTCUTS_GROUP, GtkShortcutsGroup))
#define GTK_IS_SHORTCUTS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SHORTCUTS_GROUP))
typedef struct _GtkShortcutsGroup GtkShortcutsGroup;
typedef struct _GtkShortcutsGroupClass GtkShortcutsGroupClass;
GDK_AVAILABLE_IN_ALL
GType gtk_shortcuts_group_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_4_14
void gtk_shortcuts_group_add_shortcut (GtkShortcutsGroup *self,
GtkShortcutsShortcut *shortcut);
G_END_DECLS
+29 -3
View File
@@ -53,6 +53,15 @@
* and columns.
*
* This widget is only meant to be used with [class@Gtk.ShortcutsWindow].
*
* The recommended way to construct a `GtkShortcutsSection` is with
* [class@Gtk.Builder], by using the `<child>` tag to populate a
* `GtkShortcutsSection` with one or more [class@Gtk.ShortcutsGroup]
* instances, which in turn contain one or more [class@Gtk.ShortcutsShortcut]
* objects.
*
* If you need to add a group programmatically, use
* [method@Gtk.ShortcutsSection.add_group].
*/
struct _GtkShortcutsSection
@@ -109,8 +118,6 @@ static void gtk_shortcuts_section_set_view_name (GtkShortcutsSection *self,
const char *view_name);
static void gtk_shortcuts_section_set_max_height (GtkShortcutsSection *self,
guint max_height);
static void gtk_shortcuts_section_add_group (GtkShortcutsSection *self,
GtkShortcutsGroup *group);
static void gtk_shortcuts_section_show_all (GtkShortcutsSection *self);
static void gtk_shortcuts_section_filter_groups (GtkShortcutsSection *self);
@@ -454,10 +461,29 @@ gtk_shortcuts_section_set_max_height (GtkShortcutsSection *self,
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MAX_HEIGHT]);
}
static void
/**
* gtk_shortcuts_section_add_group:
* @self: a `GtkShortcutsSection`
* @group: the `GtkShortcutsGroup` to add
*
* Adds a group to the shortcuts section.
*
* This is the programmatic equivalent to using [class@Gtk.Builder] and a
* `<child>` tag to add the child.
*
* Adding children with the `GtkBox` API is not appropriate, as
* `GtkShortcutsSection` manages its children internally.
*
* Since: 4.14
*/
void
gtk_shortcuts_section_add_group (GtkShortcutsSection *self,
GtkShortcutsGroup *group)
{
g_return_if_fail (GTK_IS_SHORTCUTS_SECTION (self));
g_return_if_fail (GTK_IS_SHORTCUTS_GROUP (group));
g_return_if_fail (gtk_widget_get_parent (GTK_WIDGET (group)) == NULL);
GtkWidget *page, *column;
page = gtk_widget_get_last_child (GTK_WIDGET (self->stack));
+5 -1
View File
@@ -23,6 +23,7 @@
#endif
#include <gdk/gdk.h>
#include <gtk/gtkshortcutsgroup.h>
G_BEGIN_DECLS
@@ -30,12 +31,15 @@ G_BEGIN_DECLS
#define GTK_SHORTCUTS_SECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SHORTCUTS_SECTION, GtkShortcutsSection))
#define GTK_IS_SHORTCUTS_SECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SHORTCUTS_SECTION))
typedef struct _GtkShortcutsSection GtkShortcutsSection;
typedef struct _GtkShortcutsSectionClass GtkShortcutsSectionClass;
GDK_AVAILABLE_IN_ALL
GType gtk_shortcuts_section_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_4_14
void gtk_shortcuts_section_add_group (GtkShortcutsSection *self,
GtkShortcutsGroup *group);
G_END_DECLS
+28 -4
View File
@@ -56,9 +56,14 @@
* showing information that is not relevant in the current application context.
*
* The recommended way to construct a `GtkShortcutsWindow` is with
* [class@Gtk.Builder], by populating a `GtkShortcutsWindow` with one or
* more `GtkShortcutsSection` objects, which contain `GtkShortcutsGroups`
* that in turn contain objects of class `GtkShortcutsShortcut`.
* [class@Gtk.Builder], by using the `<child>` tag to populate a
* `GtkShortcutsWindow` with one or more [class@Gtk.ShortcutsSection] objects,
* which contain one or more [class@Gtk.ShortcutsGroup] instances, which, in turn,
* contain [class@Gtk.ShortcutsShortcut] instances.
*
* If you need to add a section programmatically, use [method@Gtk.ShortcutsWindow.add_section]
* instead of [method@Gtk.Window.set_child], as the shortcuts window manages
* its children directly.
*
* # A simple example:
*
@@ -333,10 +338,29 @@ section_notify_cb (GObject *section,
}
}
static void
/**
* gtk_shortcuts_window_add_section:
* @self: a `GtkShortcutsWindow`
* @section: the `GtkShortcutsSection` to add
*
* Adds a section to the shortcuts window.
*
* This is the programmatic equivalent to using [class@Gtk.Builder] and a
* `<child>` tag to add the child.
*
* Using [method@Gtk.Window.set_child] is not appropriate as the shortcuts
* window manages its children internally.
*
* Since: 4.14
*/
void
gtk_shortcuts_window_add_section (GtkShortcutsWindow *self,
GtkShortcutsSection *section)
{
g_return_if_fail (GTK_IS_SHORTCUTS_WINDOW (self));
g_return_if_fail (GTK_IS_SHORTCUTS_SECTION (section));
g_return_if_fail (gtk_widget_get_parent (GTK_WIDGET (section)) == NULL);
GtkListBoxRow *row;
char *title;
char *name;
+5 -1
View File
@@ -23,6 +23,7 @@
#endif
#include <gtk/gtkwindow.h>
#include <gtk/gtkshortcutssection.h>
G_BEGIN_DECLS
@@ -30,12 +31,15 @@ G_BEGIN_DECLS
#define GTK_SHORTCUTS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SHORTCUTS_WINDOW, GtkShortcutsWindow))
#define GTK_IS_SHORTCUTS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SHORTCUTS_WINDOW))
typedef struct _GtkShortcutsWindow GtkShortcutsWindow;
GDK_AVAILABLE_IN_ALL
GType gtk_shortcuts_window_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_4_14
void gtk_shortcuts_window_add_section (GtkShortcutsWindow *self,
GtkShortcutsSection *section);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkShortcutsWindow, g_object_unref)
G_END_DECLS
+22 -4
View File
@@ -717,6 +717,16 @@ gtk_snapshot_collect_repeat (GtkSnapshot *snapshot,
return repeat_node;
}
static GskRenderNode *
gtk_snapshot_collect_discard_repeat (GtkSnapshot *snapshot,
GtkSnapshotState *state,
GskRenderNode **nodes,
guint n_nodes)
{
/* Drop the node and return nothing. */
return NULL;
}
static void
gtk_graphene_rect_scale_affine (const graphene_rect_t *rect,
float scale_x,
@@ -807,17 +817,24 @@ gtk_snapshot_push_repeat (GtkSnapshot *snapshot,
const graphene_rect_t *child_bounds)
{
GtkSnapshotState *state;
gboolean empty_child_bounds = FALSE;
graphene_rect_t real_child_bounds = { { 0 } };
float scale_x, scale_y, dx, dy;
gtk_snapshot_ensure_affine (snapshot, &scale_x, &scale_y, &dx, &dy);
if (child_bounds)
gtk_graphene_rect_scale_affine (child_bounds, scale_x, scale_y, dx, dy, &real_child_bounds);
{
gtk_graphene_rect_scale_affine (child_bounds, scale_x, scale_y, dx, dy, &real_child_bounds);
if (real_child_bounds.size.width <= 0 || real_child_bounds.size.height <= 0)
empty_child_bounds = TRUE;
}
state = gtk_snapshot_push_state (snapshot,
gtk_snapshot_get_current_state (snapshot)->transform,
gtk_snapshot_collect_repeat,
empty_child_bounds
? gtk_snapshot_collect_discard_repeat
: gtk_snapshot_collect_repeat,
NULL);
gtk_graphene_rect_scale_affine (bounds, scale_x, scale_y, dx, dy, &state->data.repeat.bounds);
@@ -2051,9 +2068,10 @@ gtk_snapshot_translate_3d (GtkSnapshot *snapshot,
* @angle: the rotation angle, in degrees (clockwise)
*
* Rotates @@snapshot's coordinate system by @angle degrees in 2D space -
* or in 3D speak, rotates around the Z axis.
* or in 3D speak, rotates around the Z axis. The rotation happens around
* the origin point of (0, 0) in the @snapshot's current coordinate system.
*
* To rotate around other axes, use [method@Gsk.Transform.rotate_3d].
* To rotate around axes other than the Z axis, use [method@Gsk.Transform.rotate_3d].
*/
void
gtk_snapshot_rotate (GtkSnapshot *snapshot,
+1 -2
View File
@@ -30,8 +30,7 @@
#include <gdk/gdk.h>
#include <gsk/gsk.h>
#include <gtk/gtkaccelgroup.h>
#include <gtk/gtkborder.h>
#include <gtk/gtkenums.h>
#include <gtk/gtkshortcut.h>
#include <gtk/gtkshortcutaction.h>
#include <gtk/gtktypes.h>
+1
View File
@@ -28,6 +28,7 @@
#include "gtkactionmuxerprivate.h"
#include "gtkatcontextprivate.h"
#include "gtkborder.h"
#include "gtkcsstypesprivate.h"
#include "gtkeventcontrollerprivate.h"
#include "gtklistlistmodelprivate.h"
+2 -1
View File
@@ -1,5 +1,5 @@
project('gtk', 'c',
version: '4.13.0',
version: '4.13.1',
default_options: [
'buildtype=debugoptimized',
'warning_level=1',
@@ -309,6 +309,7 @@ elif cc.get_id() == 'gcc' or cc.get_id() == 'clang'
'missing-declarations',
'missing-prototypes',
'nonnull',
'override-init',
'pointer-to-int-cast',
'redundant-decls',
'return-type',
+283 -61
View File
@@ -11,21 +11,20 @@
# Francisco Javier F. Serrador <serrador@cvs.gnome.org>, 2003 - 2006.
# Jorge González <jorgegonz@svn.gnome.org>, 2007, 2008, 2009, 2010, 2011.
# Daniel Mustieles <daniel.mustieles@gmail.com>, 2021-2023.
# Daniel Mustieles García <daniel.mustieles@gmail.com>, 2023.
#
msgid ""
msgstr ""
"Project-Id-Version: gtk+.master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gtk/-/issues/\n"
"POT-Creation-Date: 2023-08-05 15:54+0000\n"
"PO-Revision-Date: 2023-08-08 12:33+0200\n"
"Last-Translator: Daniel Mustieles García <daniel.mustieles@gmail.com>\n"
"POT-Creation-Date: 2023-08-20 17:48+0000\n"
"PO-Revision-Date: 2023-08-22 13:25+0200\n"
"Last-Translator: Daniel Mustieles <daniel.mustieles@gmail.com>\n"
"Language-Team: Spanish - Spain <gnome-es-list@gnome.org>\n"
"Language: es_ES\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Gtranslator 42.0\n"
"X-Generator: Gtranslator 45.alpha0\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: gdk/broadway/gdkbroadway-server.c:135
@@ -144,7 +143,7 @@ msgstr "La aplicación no soporta la API %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 "Intentando usar %s pero %s ya está en uso"
@@ -631,22 +630,22 @@ msgstr ""
#, c-format
msgid "Cannot set clipboard data. OpenClipboard() failed: 0x%lx."
msgstr ""
"No se pueden obtener los datos del portapapeles. OpenClipboard() falló: 0x"
"%lx."
"No se pueden obtener los datos del portapapeles. OpenClipboard() falló: "
"0x%lx."
#: gdk/win32/gdkclipdrop-win32.c:876
#, c-format
msgid "Cannot get clipboard data. GlobalLock(0x%p) failed: 0x%lx."
msgstr ""
"No se pueden obtener los datos del portapapeles. GlobalLock(0x%p) falló: 0x"
"%lx."
"No se pueden obtener los datos del portapapeles. GlobalLock(0x%p) falló: "
"0x%lx."
#: gdk/win32/gdkclipdrop-win32.c:887
#, c-format
msgid "Cannot get clipboard data. GlobalSize(0x%p) failed: 0x%lx."
msgstr ""
"No se pueden obtener los datos del portapapeles. GlobalSize(0x%p) falló: 0x"
"%lx."
"No se pueden obtener los datos del portapapeles. GlobalSize(0x%p) falló: "
"0x%lx."
#: gdk/win32/gdkclipdrop-win32.c:900
#, c-format
@@ -681,8 +680,8 @@ msgstr ""
#, c-format
msgid "Cannot get clipboard data. OpenClipboard() failed: 0x%lx."
msgstr ""
"No se pueden obtener los datos del portapapeles. OpenClipboard() falló: 0x"
"%lx."
"No se pueden obtener los datos del portapapeles. OpenClipboard() falló: "
"0x%lx."
#: gdk/win32/gdkclipdrop-win32.c:994
#, c-format
@@ -695,8 +694,8 @@ msgstr ""
#, c-format
msgid "Cannot get clipboard data. GetClipboardData() failed: 0x%lx."
msgstr ""
"No se pueden obtener los datos del portapapeles. GetClipboardData() falló: 0x"
"%lx."
"No se pueden obtener los datos del portapapeles. GetClipboardData() falló: "
"0x%lx."
#: gdk/win32/gdkdrop-win32.c:949
#, c-format
@@ -1081,13 +1080,13 @@ msgid "Pick a Color"
msgstr "Escoja 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 "Rojo %d%%, verde %d%%, azul %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 "Rojo %d%%, verde %d%%, azul %d%%"
@@ -1102,12 +1101,12 @@ msgid "Pick a Font"
msgstr "Escoja una tipografía"
#: 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 "Tipografía"
# src/file-manager/fm-icon-text-window.c:85
#: gtk/deprecated/gtkfontbutton.c:1152 gtk/gtkfontdialogbutton.c:614
#: gtk/deprecated/gtkfontbutton.c:1152 gtk/gtkfontdialogbutton.c:652
msgctxt "font"
msgid "None"
msgstr "Ninguna"
@@ -2258,7 +2257,7 @@ msgstr "_Abrir"
msgid "_Save"
msgstr "_Guardar"
#: 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 "Seleccionar qué tipos de archivos se muestran"
@@ -2332,7 +2331,7 @@ msgid "If you delete an item, it will be permanently lost."
msgstr "Si elimina un elemento, se perderña definitivamente."
#: 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 "_Eliminar"
@@ -2473,7 +2472,7 @@ msgstr "Programa"
msgid "Audio"
msgstr "Sonido"
#: gtk/gtkfilechooserwidget.c:3872 gtk/gtkfilefilter.c:1035
#: gtk/gtkfilechooserwidget.c:3872 gtk/gtkfilefilter.c:1032
msgid "Image"
msgstr "Imagen"
@@ -2583,7 +2582,7 @@ msgstr "Seleccionar carpetas"
msgid "Select a Folder"
msgstr "Seleccionar una carpeta"
#: gtk/gtkfilefilter.c:1048
#: gtk/gtkfilefilter.c:1045
msgid "Unspecified"
msgstr "No especificado"
@@ -2671,19 +2670,19 @@ msgstr "Cerrar"
msgid "Close the infobar"
msgstr "Cerrar la barra de información"
#: 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 "Cor_tar"
#: 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 "_Copiar"
#: 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 "_Pegar"
#: 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 "Seleccionar _todo"
@@ -3632,7 +3631,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 "Insertar _emoticono"
@@ -3697,6 +3696,7 @@ msgid "Description"
msgstr "Descripción"
#: gtk/inspector/a11y.ui:99 gtk/inspector/misc-info.ui:296
#: tools/gtk-path-tool-info.c:128
msgid "Bounds"
msgstr "Límites"
@@ -4166,7 +4166,7 @@ msgstr "Fuente:"
msgid "Defined At"
msgstr "Definida en"
#: gtk/inspector/recorder.c:1865
#: gtk/inspector/recorder.c:1922
#, c-format
msgid "Saving RenderNode failed"
msgstr "Falló al guardar el RenderNode"
@@ -7219,7 +7219,8 @@ 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-rendernode-tool-info.c:200 tools/gtk-rendernode-tool-show.c:102
#: tools/gtk-path-tool-render.c:62 tools/gtk-rendernode-tool-info.c:208
#: tools/gtk-rendernode-tool-show.c:102
msgid "FILE"
msgstr "ARCHIVO"
@@ -7251,8 +7252,8 @@ msgid "Use style from CSS file"
msgstr "Usar el estilo del archivo CSS"
#: tools/gtk-builder-tool-preview.c:187 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
#: tools/gtk-builder-tool-validate.c:268 tools/gtk-rendernode-tool-render.c:204
#: tools/gtk-rendernode-tool-show.c:109
#, c-format
msgid "Could not initialize windowing system\n"
msgstr "No se pudo inicializar el sistema de ventanas\n"
@@ -7478,6 +7479,238 @@ msgstr "%s:no existe la aplicación %s"
msgid "%s: error launching application: %s\n"
msgstr "%s: error al lanzar la aplicación: %s\n"
#: tools/gtk-path-tool.c:35
#, c-format
msgid ""
"Usage:\n"
" gtk4-path-tool [COMMAND] [OPTION…] PATH\n"
"\n"
"Perform various tasks on paths.\n"
"\n"
"Commands:\n"
" decompose Decompose the path\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-rendernode-tool [COMANDO] [OPCIÓN…] ARCHIVO\n"
"\n"
"Realiza varias tareas en rutas.\n"
"\n"
"Comandos:\n"
" decompose Descompone la ruta\n"
" show Muestra la ruta en una ventana\n"
" render Renderiza la ruta como una imagen\n"
" info Proporciona información sobre la ruta\n"
"\n"
#: tools/gtk-path-tool-decompose.c:75
msgid "Allow quadratic Bézier curves"
msgstr "Permitir curvas Bézier cuadráticas"
#: tools/gtk-path-tool-decompose.c:76
msgid "Allow cubic Bézier curves"
msgstr "Permitir curvas Bézier cúbicas"
#: tools/gtk-path-tool-decompose.c:77 tools/gtk-path-tool-info.c:88
#: tools/gtk-path-tool-render.c:63 tools/gtk-path-tool-show.c:132
msgid "PATH"
msgstr "RUTA"
#: tools/gtk-path-tool-decompose.c:89
msgid "Decompose a path."
msgstr "Descomponer una ruta."
#: tools/gtk-path-tool-decompose.c:102 tools/gtk-path-tool-info.c:112
msgid "No paths given."
msgstr "No se han dado rutas."
#: tools/gtk-path-tool-decompose.c:128
msgid "That didn't work out."
msgstr "Esto no funcionó."
#: tools/gtk-path-tool-info.c:99
msgid "Print information about a path."
msgstr "Mostrar información sobre una ruta."
#: tools/gtk-path-tool-info.c:119
msgid "Path is empty."
msgstr "La ruta está vacía."
#: tools/gtk-path-tool-info.c:125
msgid "Path is closed"
msgstr "La ruta está cerrada"
#: tools/gtk-path-tool-info.c:134
#, c-format
msgid "%d contours"
msgstr "%d contornos"
#: tools/gtk-path-tool-info.c:136
#, c-format
msgid "%d operations"
msgstr "%d operaciones"
#: tools/gtk-path-tool-info.c:140
#, c-format
msgid "%d lines"
msgstr "%d líneas"
#: tools/gtk-path-tool-info.c:145
#, c-format
msgid "%d quadratics"
msgstr "%d cuadráticas"
#: tools/gtk-path-tool-info.c:150
#, c-format
msgid "%d cubics"
msgstr "%d cúbicas"
#: tools/gtk-path-tool-render.c:52 tools/gtk-path-tool-show.c:122
msgid "Fill rule (winding, even-odd)"
msgstr "Regla de llenado (sinuoso, par-impar)"
#: tools/gtk-path-tool-render.c:52 tools/gtk-path-tool-render.c:56
#: tools/gtk-path-tool-render.c:57 tools/gtk-path-tool-render.c:58
#: tools/gtk-path-tool-render.c:59 tools/gtk-path-tool-render.c:60
#: tools/gtk-path-tool-render.c:61 tools/gtk-path-tool-show.c:122
#: tools/gtk-path-tool-show.c:126 tools/gtk-path-tool-show.c:127
#: tools/gtk-path-tool-show.c:128 tools/gtk-path-tool-show.c:129
#: tools/gtk-path-tool-show.c:130 tools/gtk-path-tool-show.c:131
msgid "VALUE"
msgstr "VALOR"
#: tools/gtk-path-tool-render.c:53 tools/gtk-path-tool-show.c:123
msgid "Foreground color"
msgstr "Color de primer plano"
#: tools/gtk-path-tool-render.c:53 tools/gtk-path-tool-render.c:54
#: tools/gtk-path-tool-show.c:123 tools/gtk-path-tool-show.c:124
msgid "COLOR"
msgstr "COLOR"
#: tools/gtk-path-tool-render.c:54 tools/gtk-path-tool-show.c:124
msgid "Background color"
msgstr "Color de fondo"
#: tools/gtk-path-tool-render.c:55 tools/gtk-path-tool-show.c:125
msgid "Stroke the path instead of filling it"
msgstr "Tachar la ruta en lugar de rellenarla"
#: tools/gtk-path-tool-render.c:56 tools/gtk-path-tool-show.c:126
msgid "Line width (number)"
msgstr "Anchura de línea (número)"
#: tools/gtk-path-tool-render.c:57 tools/gtk-path-tool-show.c:127
msgid "Line cap (butt, round, square)"
msgstr ""
#: tools/gtk-path-tool-render.c:58 tools/gtk-path-tool-show.c:128
msgid "Line join (miter, miter-clip, round, bevel, arcs)"
msgstr ""
#: tools/gtk-path-tool-render.c:59 tools/gtk-path-tool-show.c:129
msgid "Miter limit (number)"
msgstr ""
#: tools/gtk-path-tool-render.c:60 tools/gtk-path-tool-show.c:130
msgid "Dash pattern (comma-separated numbers)"
msgstr ""
#: tools/gtk-path-tool-render.c:61 tools/gtk-path-tool-show.c:131
msgid "Dash offset (number)"
msgstr ""
#: tools/gtk-path-tool-render.c:62
msgid "The output file"
msgstr "El archivo de salida"
#: tools/gtk-path-tool-render.c:81 tools/gtk-path-tool-show.c:145
msgid "Could not initialize windowing system"
msgstr "No se pudo inicializar el sistema de ventanas"
#: tools/gtk-path-tool-render.c:89
msgid "Render the path to a png image."
msgstr "Renderizar la ruta a una imagen .png."
#: tools/gtk-path-tool-render.c:102 tools/gtk-path-tool-show.c:166
msgid "No path specified"
msgstr "No se ha especificado ninguna ruta"
#: tools/gtk-path-tool-render.c:108
msgid "Can only render a single path"
msgstr "Sólo se puede renderizar una única ruta"
#: tools/gtk-path-tool-render.c:114 tools/gtk-path-tool-show.c:178
msgid "fill rule"
msgstr "regla de llenado"
#: tools/gtk-path-tool-render.c:118 tools/gtk-path-tool-show.c:182
msgid "line cap"
msgstr ""
#: tools/gtk-path-tool-render.c:119 tools/gtk-path-tool-show.c:183
msgid "line join"
msgstr ""
#: tools/gtk-path-tool-render.c:143 tools/gtk-path-tool-show.c:207
#, c-format
msgid "Failed to parse '%s' as number"
msgstr "Falló al analizar «%s» como número"
#: tools/gtk-path-tool-render.c:187
#, c-format
msgid "Saving png to '%s' failed"
msgstr "Falló al guardar el png a «%s»"
#: tools/gtk-path-tool-render.c:194
#, c-format
msgid "Output written to '%s'."
msgstr "Salida escrita en «%s»."
#: tools/gtk-path-tool-show.c:43 tools/gtk-path-tool-show.c:78
msgid "Path Preview"
msgstr "Vista previa de la ruta"
#: tools/gtk-path-tool-show.c:153
msgid "Display the path."
msgstr "Mostrar la ruta."
#: tools/gtk-path-tool-show.c:172
msgid "Can only show a single path"
msgstr "Sólo se puede mostrar una única ruta"
#: tools/gtk-path-tool-utils.c:58
#, c-format
msgid "Failed to read from standard input: %s\n"
msgstr "Falló al leer de la entrada estándar: %s\n"
#: tools/gtk-path-tool-utils.c:64
#, c-format
msgid "Error reading from standard input: %s\n"
msgstr "Error al leer de la entrada estándar: %s\n"
#: tools/gtk-path-tool-utils.c:83
#, c-format
msgid "Failed to parse '%s' as path.\n"
msgstr "Falló al analizar «%s» como ruta\n"
#: tools/gtk-path-tool-utils.c:109
#, c-format
msgid "Failed to parse '%s' as %s."
msgstr "Falló al analizar «%s» como %s."
#: tools/gtk-path-tool-utils.c:111
msgid "Possible values: "
msgstr "Valores posibles: "
#: tools/gtk-path-tool-utils.c:135
#, c-format
msgid "Could not parse '%s' as color"
msgstr "No se pudo analizar «%s» como color"
#: tools/gtk-rendernode-tool.c:35
#, c-format
msgid ""
@@ -7502,50 +7735,41 @@ msgstr ""
" show Muestra nodo\n"
" render Hace una captura del nodo\n"
#: tools/gtk-rendernode-tool-info.c:177
#: tools/gtk-rendernode-tool-info.c:185
#, c-format
msgid "Number of nodes: %u\n"
msgstr "Número de nodos: %u\n"
#: tools/gtk-rendernode-tool-info.c:184
#: tools/gtk-rendernode-tool-info.c:192
#, c-format
msgid "Depth: %u\n"
msgstr "Profundidad: %u\n"
#: tools/gtk-rendernode-tool-info.c:187
#: tools/gtk-rendernode-tool-info.c:195
#, c-format
msgid "Bounds: %g x %g\n"
msgstr "Límites: %g x %g\n"
#: tools/gtk-rendernode-tool-info.c:188
#: tools/gtk-rendernode-tool-info.c:196
#, c-format
msgid "Origin: %g %g\n"
msgstr "Origen: %g %g\n"
#: tools/gtk-rendernode-tool-info.c:209
#: tools/gtk-rendernode-tool-info.c:217
msgid "Provide information about the render node."
msgstr "Proporcionar información sobre el nodo de renderizado."
#: tools/gtk-rendernode-tool-info.c:222 tools/gtk-rendernode-tool-show.c:130
#: tools/gtk-rendernode-tool-render.c:225
#: tools/gtk-rendernode-tool-info.c:230 tools/gtk-rendernode-tool-render.c:225
#: tools/gtk-rendernode-tool-show.c:130
#, c-format
msgid "No .node file specified\n"
msgstr "No se ha especificado ningún archivo .node\n"
#: tools/gtk-rendernode-tool-info.c:228
#: tools/gtk-rendernode-tool-info.c:236
#, c-format
msgid "Can only accept a single .node file\n"
msgstr "Sólo se puede aceptar un único archivo .node\n"
#: tools/gtk-rendernode-tool-show.c:117
msgid "Show the render node."
msgstr "Mostrar el nodo de renderizado"
#: tools/gtk-rendernode-tool-show.c:136
#, c-format
msgid "Can only preview a single .node file\n"
msgstr "Sólo se puede previsualizar un único archivo .node\n"
#: tools/gtk-rendernode-tool-render.c:123
#, c-format
msgid ""
@@ -7579,6 +7803,15 @@ msgstr ""
"Sólo se puede renderizar un único archivo .node en un único archivo de "
"salida\n"
#: tools/gtk-rendernode-tool-show.c:117
msgid "Show the render node."
msgstr "Mostrar el nodo de renderizado"
#: tools/gtk-rendernode-tool-show.c:136
#, c-format
msgid "Can only preview a single .node file\n"
msgstr "Sólo se puede previsualizar un único archivo .node\n"
#: tools/gtk-rendernode-tool-utils.c:51
#, c-format
msgid "Error at %s: %s\n"
@@ -8077,10 +8310,6 @@ msgstr ""
#~ msgid "Unknown"
#~ msgstr "Desconocido"
#~ msgctxt "Script"
#~ msgid "Balinese"
#~ msgstr "Balinés"
#~ msgctxt "Script"
#~ msgid "Cuneiform"
#~ msgstr "Cuneiforme"
@@ -8823,10 +9052,6 @@ msgstr ""
#~ msgid "_Print"
#~ msgstr "_Imprimir"
#~ msgctxt "Stock label"
#~ msgid "Print Pre_view"
#~ msgstr "_Vista previa de impresión"
#~ msgctxt "Stock label"
#~ msgid "_Properties"
#~ msgstr "_Propiedades"
@@ -9024,9 +9249,6 @@ msgstr ""
#~ msgid "Size of the palette in 8 bit mode"
#~ msgstr "Tamaño de la paleta en modo 8 bits"
#~ msgid "COLORS"
#~ msgstr "COLORES"
#~ msgid "Move"
#~ msgstr "Mover"
+132 -88
View File
@@ -12,8 +12,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gtk+ 2.6\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gtk/-/issues/\n"
"POT-Creation-Date: 2023-08-14 13:16+0000\n"
"PO-Revision-Date: 2023-08-15 02:04+0330\n"
"POT-Creation-Date: 2023-08-22 16:19+0000\n"
"PO-Revision-Date: 2023-08-23 03:48+0330\n"
"Last-Translator: Danial Behzadi <dani.behzi@ubuntu.com>\n"
"Language-Team: Persian <>\n"
"Language: fa\n"
@@ -569,7 +569,7 @@ msgstr "خواندن داده‌ها در ردیف %Id شکست خورد"
#: 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 "هیچ قالب انتقال سازگاری پیدا نشد"
@@ -763,11 +763,11 @@ msgid "Opening %d Item"
msgid_plural "Opening %d Items"
msgstr[0] "درحال گشودن %Id مورد"
#: gdk/x11/gdkclipboard-x11.c:475
#: gdk/x11/gdkclipboard-x11.c:477
msgid "Clipboard manager could not store selection."
msgstr "مدیر تخته‌گیره نتوانست گزینش را ذخیره کند."
#: gdk/x11/gdkclipboard-x11.c:655
#: gdk/x11/gdkclipboard-x11.c:657
msgid "Cannot store clipboard. No clipboard manager is active."
msgstr "نتوانست تخته‌گیره را ذخیره کند. هیچ مدیر تخته‌گیره‌ای فعّال نیست."
@@ -1031,13 +1031,13 @@ msgid "Pick a Color"
msgstr "یک رنگ بردارید"
#: 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 "قرمز ٪%Id، سبز ٪%Id، آبی ٪%Id، آلفا ٪%Id"
#: 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 "قرمز ٪%Id، سبز ٪%Id، آبی ٪%Id"
@@ -1052,12 +1052,12 @@ msgid "Pick a Font"
msgstr "یک قلم بردارید"
#: 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 "قلم"
# farmaan
#: gtk/deprecated/gtkfontbutton.c:1152 gtk/gtkfontdialogbutton.c:614
#: gtk/deprecated/gtkfontbutton.c:1152 gtk/gtkfontdialogbutton.c:652
msgctxt "font"
msgid "None"
msgstr "هیچ‌کدام"
@@ -2198,7 +2198,7 @@ msgstr "_گشودن"
msgid "_Save"
msgstr "_ذخیره"
#: 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 "انتخاب این که کدام نوع پرونده‌ها نمایش داده شوند"
@@ -2411,7 +2411,7 @@ msgstr "برنامه"
msgid "Audio"
msgstr "صدا"
#: gtk/gtkfilechooserwidget.c:3872 gtk/gtkfilefilter.c:1035
#: gtk/gtkfilechooserwidget.c:3872 gtk/gtkfilefilter.c:1032
msgid "Image"
msgstr "تصویر"
@@ -2520,7 +2520,7 @@ msgstr "گزینش شاخه‌ها"
msgid "Select a Folder"
msgstr "شاخه‌ای را برگزنید"
#: gtk/gtkfilefilter.c:1048
#: gtk/gtkfilefilter.c:1045
msgid "Unspecified"
msgstr "نامشخّص"
@@ -3621,7 +3621,7 @@ msgid "Description"
msgstr "شرح"
#: gtk/inspector/a11y.ui:99 gtk/inspector/misc-info.ui:296
#: tools/gtk-path-tool-info.c:72
#: tools/gtk-path-tool-info.c:128
msgid "Bounds"
msgstr "مزرها"
@@ -7125,7 +7125,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:62 tools/gtk-rendernode-tool-info.c:208
#: tools/gtk-path-tool-render.c:55 tools/gtk-rendernode-tool-info.c:208
#: tools/gtk-rendernode-tool-show.c:102
msgid "FILE"
msgstr "پرونده"
@@ -7417,8 +7417,8 @@ msgstr "اجازه به منحی‌های درجه دوم بزیه"
msgid "Allow cubic Bézier curves"
msgstr "اجازه به منحی‌های درجه سوم بزیه"
#: tools/gtk-path-tool-decompose.c:77 tools/gtk-path-tool-info.c:34
#: tools/gtk-path-tool-render.c:63 tools/gtk-path-tool-show.c:132
#: 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
msgid "PATH"
msgstr "PATH"
@@ -7426,124 +7426,169 @@ msgstr "PATH"
msgid "Decompose a path."
msgstr "باز کردن یک مسیر."
#: tools/gtk-path-tool-decompose.c:102 tools/gtk-path-tool-info.c:58
#: tools/gtk-path-tool-decompose.c:102 tools/gtk-path-tool-info.c:112
msgid "No paths given."
msgstr "مسیری داده نشده"
msgstr "مسیری داده نشده."
#: tools/gtk-path-tool-decompose.c:128
msgid "That didn't work out."
msgstr "کار نکرد."
#: tools/gtk-path-tool-info.c:45
#: tools/gtk-path-tool-info.c:99
msgid "Print information about a path."
msgstr "چاپ اطّلاعات دربارهٔ یک مسیر."
#: tools/gtk-path-tool-info.c:65
#: tools/gtk-path-tool-info.c:119
msgid "Path is empty."
msgstr "مسیر خالی است."
#: tools/gtk-path-tool-info.c:69
#: tools/gtk-path-tool-info.c:125
msgid "Path is closed"
msgstr "مسیر بسته است"
#: tools/gtk-path-tool-render.c:52 tools/gtk-path-tool-show.c:122
msgid "Fill rule (winding, even-odd)"
msgstr "قاعدهٔ پر کردن (winding, even-odd)"
#: tools/gtk-path-tool-info.c:134
#, c-format
msgid "%d contours"
msgstr "%Id خط فاصل"
#: tools/gtk-path-tool-render.c:52 tools/gtk-path-tool-render.c:56
#: tools/gtk-path-tool-render.c:57 tools/gtk-path-tool-render.c:58
#: tools/gtk-path-tool-render.c:59 tools/gtk-path-tool-render.c:60
#: tools/gtk-path-tool-render.c:61 tools/gtk-path-tool-show.c:122
#: tools/gtk-path-tool-show.c:126 tools/gtk-path-tool-show.c:127
#: tools/gtk-path-tool-show.c:128 tools/gtk-path-tool-show.c:129
#: tools/gtk-path-tool-show.c:130 tools/gtk-path-tool-show.c:131
msgid "VALUE"
msgstr "VALUE"
#: tools/gtk-path-tool-info.c:136
#, c-format
msgid "%d operations"
msgstr "%Id عملیات"
#: tools/gtk-path-tool-info.c:140
#, c-format
msgid "%d lines"
msgstr "%Id خط"
#: tools/gtk-path-tool-info.c:145
#, c-format
msgid "%d quadratics"
msgstr "%Id درجه دوم"
#: tools/gtk-path-tool-info.c:150
#, c-format
msgid "%d cubics"
msgstr "%Id درجه سوم"
#: tools/gtk-path-tool-render.c:53 tools/gtk-path-tool-show.c:123
msgid "Foreground color"
msgstr "رنگ پیش‌زمینه"
#: tools/gtk-path-tool-render.c:53 tools/gtk-path-tool-render.c:54
#: tools/gtk-path-tool-show.c:123 tools/gtk-path-tool-show.c:124
msgid "COLOR"
msgstr "COLOR"
msgid "Fill the path (the default)"
msgstr "پر کردن مسیر (پیش‌گزیده)"
#: tools/gtk-path-tool-render.c:54 tools/gtk-path-tool-show.c:124
msgid "Background color"
msgstr "رنگ پس‌زمینه"
msgid "Stroke the path"
msgstr "خط‌کشی مسیر"
#: tools/gtk-path-tool-render.c:55 tools/gtk-path-tool-show.c:125
msgid "Stroke the path instead of filling it"
msgstr "خط‌کشی دور مسیر به جای پر کردنش"
#: tools/gtk-path-tool-render.c:56 tools/gtk-path-tool-show.c:126
msgid "Line width (number)"
msgstr "پهنای خط (عدد)"
#: tools/gtk-path-tool-render.c:57 tools/gtk-path-tool-show.c:127
msgid "Line cap (butt, round, square)"
msgstr "کلاهک خط (butt, round, square)"
#: tools/gtk-path-tool-render.c:58 tools/gtk-path-tool-show.c:128
msgid "Line join (miter, miter-clip, round, bevel, arcs)"
msgstr "پیوستن خط (miter, miter-clip, round, bevel, arcs)"
#: tools/gtk-path-tool-render.c:59 tools/gtk-path-tool-show.c:129
msgid "Miter limit (number)"
msgstr "کران تاج (عدد)"
#: tools/gtk-path-tool-render.c:60 tools/gtk-path-tool-show.c:130
msgid "Dash pattern (comma-separated numbers)"
msgstr "الگوی نقطه‌چین (عددهای جدا شده با کاما)"
#: tools/gtk-path-tool-render.c:61 tools/gtk-path-tool-show.c:131
msgid "Dash offset (number)"
msgstr "انحراف از مبدأ نقطه‌چین (عدد)"
#: tools/gtk-path-tool-render.c:62
#: tools/gtk-path-tool-render.c:55
msgid "The output file"
msgstr "پروندهٔ خروجی"
#: tools/gtk-path-tool-render.c:81 tools/gtk-path-tool-show.c:145
#: tools/gtk-path-tool-render.c:56 tools/gtk-path-tool-show.c:125
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
msgid "COLOR"
msgstr "COLOR"
#: tools/gtk-path-tool-render.c:57 tools/gtk-path-tool-show.c:126
msgid "Background color"
msgstr "رنگ پس‌زمینه"
#: tools/gtk-path-tool-render.c:62 tools/gtk-path-tool-show.c:131
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
msgid "VALUE"
msgstr "VALUE"
#: tools/gtk-path-tool-render.c:66 tools/gtk-path-tool-show.c:135
msgid "Line width (number)"
msgstr "پهنای خط (عدد)"
#: tools/gtk-path-tool-render.c:67 tools/gtk-path-tool-show.c:136
msgid "Line cap (butt, round, square)"
msgstr "کلاهک خط (butt, round, square)"
#: tools/gtk-path-tool-render.c:68 tools/gtk-path-tool-show.c:137
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
msgid "Miter limit (number)"
msgstr "کران تاج (عدد)"
#: tools/gtk-path-tool-render.c:70 tools/gtk-path-tool-show.c:139
msgid "Dash pattern (comma-separated numbers)"
msgstr "الگوی نقطه‌چین (عددهای جدا شده با کاما)"
#: tools/gtk-path-tool-render.c:71 tools/gtk-path-tool-show.c:140
msgid "Dash offset (number)"
msgstr "انحراف از مبدأ نقطه‌چین (عدد)"
#: tools/gtk-path-tool-render.c:90 tools/gtk-path-tool-show.c:153
msgid "Could not initialize windowing system"
msgstr "نتوانست سامانهٔ پنجره را راه‌اندازی کند"
#: tools/gtk-path-tool-render.c:89
#: tools/gtk-path-tool-render.c:97
msgid "Render the path to a png image."
msgstr "پرداخت مسیر در یک تصویر png."
#: tools/gtk-path-tool-render.c:102 tools/gtk-path-tool-show.c:166
#: tools/gtk-path-tool-render.c:102 tools/gtk-path-tool-show.c:164
msgid "Options related to filling"
msgstr "گزینه‌های مربوط به پر کردن"
#: tools/gtk-path-tool-render.c:103 tools/gtk-path-tool-show.c:165
msgid "Show help for fill options"
msgstr "نمالیش راهنما برای گزینه‌های پر کردن"
#: tools/gtk-path-tool-render.c:110 tools/gtk-path-tool-show.c:172
msgid "Options related to stroking"
msgstr "گزینه‌های مربوط به خط‌کشی"
#: tools/gtk-path-tool-render.c:111 tools/gtk-path-tool-show.c:173
msgid "Show help for stroke options"
msgstr "نمالیش راهنما برای گزینه‌های خط‌کشی"
#: tools/gtk-path-tool-render.c:128 tools/gtk-path-tool-show.c:190
msgid "No path specified"
msgstr "مسیری مشخّص نشده"
#: tools/gtk-path-tool-render.c:108
#: tools/gtk-path-tool-render.c:134
msgid "Can only render a single path"
msgstr "تنها می‌تواند یک تک‌مسیر را پرداخت کند"
#: tools/gtk-path-tool-render.c:114 tools/gtk-path-tool-show.c:178
#: tools/gtk-path-tool-render.c:140 tools/gtk-path-tool-show.c:202
msgid "fill rule"
msgstr "قاعدهٔ پر کردن"
#: tools/gtk-path-tool-render.c:118 tools/gtk-path-tool-show.c:182
#: tools/gtk-path-tool-render.c:144 tools/gtk-path-tool-show.c:206
msgid "line cap"
msgstr "کلاهک خط"
#: tools/gtk-path-tool-render.c:119 tools/gtk-path-tool-show.c:183
#: tools/gtk-path-tool-render.c:145 tools/gtk-path-tool-show.c:207
msgid "line join"
msgstr "پیوستن خط"
#: tools/gtk-path-tool-render.c:143 tools/gtk-path-tool-show.c:207
#: 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:187
#: tools/gtk-path-tool-render.c:213
#, c-format
msgid "Saving png to '%s' failed"
msgstr "ذخیرهٔ png در «%s» شکست خورد"
#: tools/gtk-path-tool-render.c:194
#: tools/gtk-path-tool-render.c:220
#, c-format
msgid "Output written to '%s'."
msgstr "خروجی در «%s» نوشته شد."
@@ -7552,11 +7597,11 @@ msgstr "خروجی در «%s» نوشته شد."
msgid "Path Preview"
msgstr "پیش‌نمایش مسیر"
#: tools/gtk-path-tool-show.c:153
#: tools/gtk-path-tool-show.c:161
msgid "Display the path."
msgstr "نمایش مسیر."
#: tools/gtk-path-tool-show.c:172
#: tools/gtk-path-tool-show.c:196
msgid "Can only show a single path"
msgstr "تنها می‌تواند یک تک‌مسیر را نمایش دهد"
@@ -7578,7 +7623,7 @@ msgstr "شکست در تجزیهٔ «%s» به شکل مسیر.\n"
#: tools/gtk-path-tool-utils.c:109
#, c-format
msgid "Failed to parse '%s' as %s."
msgstr "شکست در تجزیهٔ «%s» به شکل %s"
msgstr "شکست در تجزیهٔ «%s» به شکل %s."
#: tools/gtk-path-tool-utils.c:111
msgid "Possible values: "
@@ -7805,6 +7850,9 @@ msgstr ""
"اگر به‌راستی می‌خواهید این‌جا انبارهٔ نقشکی ایجاد کنید، از --ignore-theme-index "
"استفاده کنید.\n"
#~ msgid "Stroke the path instead of filling it"
#~ msgstr "خط‌کشی دور مسیر به جای پر کردنش"
#~ msgid "Tab list"
#~ msgstr "فهرست زبانه"
@@ -8195,10 +8243,6 @@ msgstr ""
#~ msgid "Unknown"
#~ msgstr "ناشناخته"
#~ msgctxt "Script"
#~ msgid "Balinese"
#~ msgstr "بالیایی"
#~ msgctxt "Script"
#~ msgid "Cuneiform"
#~ msgstr "میخی"
+117 -85
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-15 19:28+0000\n"
"PO-Revision-Date: 2023-08-16 01:39+0200\n"
"POT-Creation-Date: 2023-08-23 19:17+0000\n"
"PO-Revision-Date: 2023-08-24 08:19+0200\n"
"Last-Translator: Fran Dieguez <frandieguez@gnome.org>\n"
"Language-Team: Galician <proxecto@trasno.gal>\n"
"Language: gl\n"
@@ -582,7 +582,7 @@ msgstr "Fallou a lectura o dato na 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 "Non se atopou un formato de transferencia compatíbel"
@@ -807,11 +807,11 @@ msgid_plural "Opening %d Items"
msgstr[0] "Abrindo %d elemento"
msgstr[1] "Abrindo %d elementos"
#: gdk/x11/gdkclipboard-x11.c:475
#: gdk/x11/gdkclipboard-x11.c:477
msgid "Clipboard manager could not store selection."
msgstr "O xestor do portapapeis non pode almacenar a selección."
#: gdk/x11/gdkclipboard-x11.c:655
#: gdk/x11/gdkclipboard-x11.c:657
msgid "Cannot store clipboard. No clipboard manager is active."
msgstr ""
"Non é posíbel almacenar o portapapeis. Non hai un xestor de portapapeis "
@@ -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:128
#: tools/gtk-path-tool-info.c:133
msgid "Bounds"
msgstr "Limiares"
@@ -7211,7 +7211,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:62 tools/gtk-rendernode-tool-info.c:208
#: tools/gtk-path-tool-render.c:55 tools/gtk-rendernode-tool-info.c:208
#: tools/gtk-rendernode-tool-show.c:102
msgid "FILE"
msgstr "FICHEIRO"
@@ -7501,166 +7501,195 @@ msgstr ""
" info Fornece información da ruta\n"
"\n"
#: tools/gtk-path-tool-decompose.c:75
#: tools/gtk-path-tool-decompose.c:80
msgid "Allow quadratic Bézier curves"
msgstr "Permitir curvas Bézier cuadráticas"
#: tools/gtk-path-tool-decompose.c:76
#: tools/gtk-path-tool-decompose.c:81
msgid "Allow cubic Bézier curves"
msgstr "Permitir curvas Bézier cúbicas"
#: tools/gtk-path-tool-decompose.c:77 tools/gtk-path-tool-info.c:88
#: tools/gtk-path-tool-render.c:63 tools/gtk-path-tool-show.c:132
#: tools/gtk-path-tool-decompose.c:82
msgid "Allow elliptical arcs"
msgstr "Permitir arcos elípticos"
#: 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
msgid "PATH"
msgstr "RUTA"
#: tools/gtk-path-tool-decompose.c:89
#: tools/gtk-path-tool-decompose.c:95
msgid "Decompose a path."
msgstr "Descompoñer unha ruta."
#: tools/gtk-path-tool-decompose.c:102 tools/gtk-path-tool-info.c:112
#: tools/gtk-path-tool-decompose.c:108 tools/gtk-path-tool-info.c:117
msgid "No paths given."
msgstr "Non se forneceron rutas."
#: tools/gtk-path-tool-decompose.c:128
#: tools/gtk-path-tool-decompose.c:136
msgid "That didn't work out."
msgstr "Iso non funcionou."
#: tools/gtk-path-tool-info.c:99
#: tools/gtk-path-tool-info.c:104
msgid "Print information about a path."
msgstr "Mostra a información sobre a ruta."
#: tools/gtk-path-tool-info.c:119
#: tools/gtk-path-tool-info.c:124
msgid "Path is empty."
msgstr "A ruta está baleira."
#: tools/gtk-path-tool-info.c:125
#: tools/gtk-path-tool-info.c:130
msgid "Path is closed"
msgstr "A ruta está pechada"
#: tools/gtk-path-tool-info.c:134
#: tools/gtk-path-tool-info.c:139
#, c-format
msgid "%d contours"
msgstr "%d contornos"
#: tools/gtk-path-tool-info.c:136
#: tools/gtk-path-tool-info.c:141
#, c-format
msgid "%d operations"
msgstr "%d operacións"
#: tools/gtk-path-tool-info.c:140
#: tools/gtk-path-tool-info.c:145
#, c-format
msgid "%d lines"
msgstr "%d liñas"
#: tools/gtk-path-tool-info.c:145
#: tools/gtk-path-tool-info.c:150
#, c-format
msgid "%d quadratics"
msgstr "%d cuadráticas"
#: tools/gtk-path-tool-info.c:150
#: tools/gtk-path-tool-info.c:155
#, c-format
msgid "%d cubics"
msgstr "%d cúbicas"
#: tools/gtk-path-tool-render.c:52 tools/gtk-path-tool-show.c:122
msgid "Fill rule (winding, even-odd)"
msgstr "Regra de recheo (sinuoso, par-impar)"
#: tools/gtk-path-tool-render.c:52 tools/gtk-path-tool-render.c:56
#: tools/gtk-path-tool-render.c:57 tools/gtk-path-tool-render.c:58
#: tools/gtk-path-tool-render.c:59 tools/gtk-path-tool-render.c:60
#: tools/gtk-path-tool-render.c:61 tools/gtk-path-tool-show.c:122
#: tools/gtk-path-tool-show.c:126 tools/gtk-path-tool-show.c:127
#: tools/gtk-path-tool-show.c:128 tools/gtk-path-tool-show.c:129
#: tools/gtk-path-tool-show.c:130 tools/gtk-path-tool-show.c:131
msgid "VALUE"
msgstr "VALOR"
#: tools/gtk-path-tool-info.c:160
#, c-format
msgid "%d arcs"
msgstr "%d arcos"
#: tools/gtk-path-tool-render.c:53 tools/gtk-path-tool-show.c:123
msgid "Foreground color"
msgstr "Cor do primeiro plano"
#: tools/gtk-path-tool-render.c:53 tools/gtk-path-tool-render.c:54
#: tools/gtk-path-tool-show.c:123 tools/gtk-path-tool-show.c:124
msgid "COLOR"
msgstr "COR"
msgid "Fill the path (the default)"
msgstr "Completar a ruta (a predeterminada)"
#: tools/gtk-path-tool-render.c:54 tools/gtk-path-tool-show.c:124
msgid "Background color"
msgstr "Cor do fondo"
msgid "Stroke the path"
msgstr "Riscar a ruta"
#: tools/gtk-path-tool-render.c:55 tools/gtk-path-tool-show.c:125
msgid "Stroke the path instead of filling it"
msgstr "Traza a ruta en lugar de enchela"
#: tools/gtk-path-tool-render.c:56 tools/gtk-path-tool-show.c:126
msgid "Line width (number)"
msgstr "Anchura da liña (número)"
#: tools/gtk-path-tool-render.c:57 tools/gtk-path-tool-show.c:127
msgid "Line cap (butt, round, square)"
msgstr "Límite de liña (tope, redondo, cadrada)"
#: tools/gtk-path-tool-render.c:58 tools/gtk-path-tool-show.c:128
msgid "Line join (miter, miter-clip, round, bevel, arcs)"
msgstr "Unión de liña (inglete, inglete-clip, redondo, bisel, arcos)"
#: tools/gtk-path-tool-render.c:59 tools/gtk-path-tool-show.c:129
msgid "Miter limit (number)"
msgstr "Límite de inglete (número)"
#: tools/gtk-path-tool-render.c:60 tools/gtk-path-tool-show.c:130
msgid "Dash pattern (comma-separated numbers)"
msgstr "Patrón de guión (números separados por comas)"
#: tools/gtk-path-tool-render.c:61 tools/gtk-path-tool-show.c:131
msgid "Dash offset (number)"
msgstr "Desprazamento do guión (número)"
#: tools/gtk-path-tool-render.c:62
#: tools/gtk-path-tool-render.c:55
msgid "The output file"
msgstr "O ficheiro de saída"
#: tools/gtk-path-tool-render.c:81 tools/gtk-path-tool-show.c:145
#: tools/gtk-path-tool-render.c:56 tools/gtk-path-tool-show.c:125
msgid "Foreground color"
msgstr "Cor do primeiro plano"
#: 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
msgid "COLOR"
msgstr "COR"
#: tools/gtk-path-tool-render.c:57 tools/gtk-path-tool-show.c:126
msgid "Background color"
msgstr "Cor do fondo"
#: tools/gtk-path-tool-render.c:62 tools/gtk-path-tool-show.c:131
msgid "Fill rule (winding, even-odd)"
msgstr "Regra de recheo (sinuoso, par-impar)"
#: 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
msgid "VALUE"
msgstr "VALOR"
#: tools/gtk-path-tool-render.c:66 tools/gtk-path-tool-show.c:135
msgid "Line width (number)"
msgstr "Anchura da liña (número)"
#: tools/gtk-path-tool-render.c:67 tools/gtk-path-tool-show.c:136
msgid "Line cap (butt, round, square)"
msgstr "Límite de liña (tope, redondo, cadrada)"
#: tools/gtk-path-tool-render.c:68 tools/gtk-path-tool-show.c:137
msgid "Line join (miter, miter-clip, round, bevel, arcs)"
msgstr "Unión de liña (inglete, inglete-clip, redondo, bisel, arcos)"
#: tools/gtk-path-tool-render.c:69 tools/gtk-path-tool-show.c:138
msgid "Miter limit (number)"
msgstr "Límite de inglete (número)"
#: tools/gtk-path-tool-render.c:70 tools/gtk-path-tool-show.c:139
msgid "Dash pattern (comma-separated numbers)"
msgstr "Patrón de guión (números separados por comas)"
#: tools/gtk-path-tool-render.c:71 tools/gtk-path-tool-show.c:140
msgid "Dash offset (number)"
msgstr "Desprazamento do guión (número)"
#: tools/gtk-path-tool-render.c:90 tools/gtk-path-tool-show.c:153
msgid "Could not initialize windowing system"
msgstr "Non foi posíbel inicializar sistema de xanelas"
#: tools/gtk-path-tool-render.c:89
#: tools/gtk-path-tool-render.c:97
msgid "Render the path to a png image."
msgstr "Renderiza a ruta a unha imaxe png."
#: tools/gtk-path-tool-render.c:102 tools/gtk-path-tool-show.c:166
#: tools/gtk-path-tool-render.c:102 tools/gtk-path-tool-show.c:164
msgid "Options related to filling"
msgstr "Opcións relacionadas para rechear"
#: tools/gtk-path-tool-render.c:103 tools/gtk-path-tool-show.c:165
msgid "Show help for fill options"
msgstr "Mostrar axuda para as opcións de recheo"
#: tools/gtk-path-tool-render.c:110 tools/gtk-path-tool-show.c:172
msgid "Options related to stroking"
msgstr "Opcións relacionadas para riscar"
#: tools/gtk-path-tool-render.c:111 tools/gtk-path-tool-show.c:173
msgid "Show help for stroke options"
msgstr "Mostrar axuda para as opcións de riscado"
#: tools/gtk-path-tool-render.c:128 tools/gtk-path-tool-show.c:190
msgid "No path specified"
msgstr "Ruta non especificada"
#: tools/gtk-path-tool-render.c:108
#: tools/gtk-path-tool-render.c:134
msgid "Can only render a single path"
msgstr "Só pode renderizar unha única ruta"
#: tools/gtk-path-tool-render.c:114 tools/gtk-path-tool-show.c:178
#: tools/gtk-path-tool-render.c:140 tools/gtk-path-tool-show.c:202
msgid "fill rule"
msgstr "regra de recheo"
#: tools/gtk-path-tool-render.c:118 tools/gtk-path-tool-show.c:182
#: tools/gtk-path-tool-render.c:144 tools/gtk-path-tool-show.c:206
msgid "line cap"
msgstr "límite de liña"
#: tools/gtk-path-tool-render.c:119 tools/gtk-path-tool-show.c:183
#: tools/gtk-path-tool-render.c:145 tools/gtk-path-tool-show.c:207
msgid "line join"
msgstr "unión de liña"
#: tools/gtk-path-tool-render.c:143 tools/gtk-path-tool-show.c:207
#: tools/gtk-path-tool-render.c:169 tools/gtk-path-tool-show.c:231
#, c-format
msgid "Failed to parse '%s' as number"
msgstr "Produciuse un erro ao analizar «%s» como un número"
#: tools/gtk-path-tool-render.c:187
#: tools/gtk-path-tool-render.c:213
#, c-format
msgid "Saving png to '%s' failed"
msgstr "Fallou o gardado do png en «%s»"
#: tools/gtk-path-tool-render.c:194
#: tools/gtk-path-tool-render.c:220
#, c-format
msgid "Output written to '%s'."
msgstr "Saída escrita en «%s»."
@@ -7669,11 +7698,11 @@ msgstr "Saída escrita en «%s»."
msgid "Path Preview"
msgstr "Vista previa"
#: tools/gtk-path-tool-show.c:153
#: tools/gtk-path-tool-show.c:161
msgid "Display the path."
msgstr "Mostrar a ruta."
#: tools/gtk-path-tool-show.c:172
#: tools/gtk-path-tool-show.c:196
msgid "Can only show a single path"
msgstr "Só pode mostrar unha única ruta"
@@ -7919,3 +7948,6 @@ msgstr ""
"Non hai ficheiro de índice de tema en «%s».\n"
"Se está seguro de que quere crear unha caché de iconas aquí, use --ignore-"
"theme-index.\n"
#~ msgid "Stroke the path instead of filling it"
#~ msgstr "Traza a ruta en lugar de enchela"
+101 -78
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-15 19:28+0000\n"
"PO-Revision-Date: 2023-08-16 05:35+0200\n"
"POT-Creation-Date: 2023-08-22 16:19+0000\n"
"PO-Revision-Date: 2023-08-22 23:12+0200\n"
"Last-Translator: Ekaterine Papava <papava.e@gtu.ge>\n"
"Language-Team: Georgian <http://mail.gnome.org/mailman/listinfo/gnome-ge-"
"list>\n"
@@ -567,7 +567,7 @@ msgstr "მონაცემების კითხვის შეცდო
#: 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 "გადატანის თავსებადი ფორმატი ნაპოვნი არაა"
@@ -795,11 +795,11 @@ msgid "Opening %d Item"
msgid_plural "Opening %d Items"
msgstr[0] "იხსნება %d საგანი"
#: gdk/x11/gdkclipboard-x11.c:475
#: gdk/x11/gdkclipboard-x11.c:477
msgid "Clipboard manager could not store selection."
msgstr "გაცვლის ბაფერის მმართველის შეცდომა მონიშნულის დამახსოვრებისას."
#: gdk/x11/gdkclipboard-x11.c:655
#: gdk/x11/gdkclipboard-x11.c:657
msgid "Cannot store clipboard. No clipboard manager is active."
msgstr ""
"გაცვლის ბაფერის დამახსოვრება შეუძლებელია. ბაფერის მმართველი აქტიური არაა."
@@ -1010,7 +1010,7 @@ msgstr "GNOME-ის პროგრამის გაშვების შე
#: gtk/deprecated/gtkappchooserwidget.c:525
msgid "Default App"
msgstr "ნაგულისხმეი აპი"
msgstr "ნაგულისხმეი აპი"
#: gtk/deprecated/gtkappchooserwidget.c:575
#, c-format
@@ -2602,7 +2602,7 @@ msgstr "ოპტიკური ზომა"
#: gtk/gtkfontchooserwidget.c:2109
msgctxt "Font feature value"
msgid "Default"
msgstr "ნაგულისხმეი"
msgstr "ნაგულისხმეი"
#: gtk/gtkfontchooserwidget.c:2126
msgctxt "Font feature value"
@@ -2611,7 +2611,7 @@ msgstr "ჩართვა"
#: gtk/gtkfontchooserwidget.c:2457
msgid "Default"
msgstr "ნაგულისხმეი"
msgstr "ნაგულისხმეი"
#: gtk/gtkfontchooserwidget.c:2519
msgid "Ligatures"
@@ -4111,7 +4111,7 @@ msgstr "განულება"
#: gtk/inspector/prop-editor.c:1592
msgctxt "GtkSettings source"
msgid "Default"
msgstr "ნაგულისხმეი"
msgstr "ნაგულისხმეი"
#: gtk/inspector/prop-editor.c:1595
msgctxt "GtkSettings source"
@@ -6652,7 +6652,7 @@ msgstr "პრინტერის ატრიბუტების მის
#: modules/printbackends/gtkprintbackendcups.c:1198
#, c-format
msgid "Authentication is required to get default printer of %s"
msgstr "%s-ის ნაგულისხმეი პრინტერის მისაღებად საჭიროა ავთენტიკაცია"
msgstr "%s-ის ნაგულისხმეი პრინტერის მისაღებად საჭიროა ავთენტიკაცია"
#: modules/printbackends/gtkprintbackendcups.c:1201
#, c-format
@@ -6821,7 +6821,7 @@ msgstr "ავტომატური არჩევა"
#: modules/printbackends/gtkprintbackendcups.c:4616
msgctxt "printing option value"
msgid "Printer Default"
msgstr "ნაგულისხმეი პრინტერი"
msgstr "ნაგულისხმეი პრინტერი"
#. Translators: this is an option of "GhostScript"
#: modules/printbackends/gtkprintbackendcups.c:4618
@@ -6966,7 +6966,7 @@ msgstr "თარო %d"
#: modules/printbackends/gtkprintbackendcups.c:5198
msgid "Printer Default"
msgstr "ნაგულისხმეი პრინტერი"
msgstr "ნაგულისხმეი პრინტერი"
#. Translators, this string is used to label the job priority option
#. * in the print dialog
@@ -7184,7 +7184,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:62 tools/gtk-rendernode-tool-info.c:208
#: tools/gtk-path-tool-render.c:55 tools/gtk-rendernode-tool-info.c:208
#: tools/gtk-rendernode-tool-show.c:102
msgid "FILE"
msgstr "FILE"
@@ -7479,7 +7479,7 @@ 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:63 tools/gtk-path-tool-show.c:132
#: tools/gtk-path-tool-render.c:58 tools/gtk-path-tool-show.c:127
msgid "PATH"
msgstr "ბილიკი"
@@ -7532,104 +7532,124 @@ msgstr "%d კვადრატი"
msgid "%d cubics"
msgstr "%d კუბი"
#: tools/gtk-path-tool-render.c:52 tools/gtk-path-tool-show.c:122
msgid "Fill rule (winding, even-odd)"
msgstr "შევსების წესი (winding, even-odd)"
#: tools/gtk-path-tool-render.c:52 tools/gtk-path-tool-render.c:56
#: tools/gtk-path-tool-render.c:57 tools/gtk-path-tool-render.c:58
#: tools/gtk-path-tool-render.c:59 tools/gtk-path-tool-render.c:60
#: tools/gtk-path-tool-render.c:61 tools/gtk-path-tool-show.c:122
#: tools/gtk-path-tool-show.c:126 tools/gtk-path-tool-show.c:127
#: tools/gtk-path-tool-show.c:128 tools/gtk-path-tool-show.c:129
#: tools/gtk-path-tool-show.c:130 tools/gtk-path-tool-show.c:131
msgid "VALUE"
msgstr "მნიშვნელობა"
#: tools/gtk-path-tool-render.c:53 tools/gtk-path-tool-show.c:123
msgid "Foreground color"
msgstr "წინა პლანის ფერი"
#: tools/gtk-path-tool-render.c:53 tools/gtk-path-tool-render.c:54
#: tools/gtk-path-tool-show.c:123 tools/gtk-path-tool-show.c:124
msgid "COLOR"
msgstr "ფერი"
msgid "Fill the path (the default)"
msgstr "კონტურის შევსება (ნაგულისხმევი)"
#: tools/gtk-path-tool-render.c:54 tools/gtk-path-tool-show.c:124
msgid "Background color"
msgstr "ონის ფერი"
msgid "Stroke the path"
msgstr "ონტურის სვლა"
#: tools/gtk-path-tool-render.c:55 tools/gtk-path-tool-show.c:125
msgid "Stroke the path instead of filling it"
msgstr "ბილიკის შემოვლება მისი შევსების მაგიერ"
#: tools/gtk-path-tool-render.c:56 tools/gtk-path-tool-show.c:126
msgid "Line width (number)"
msgstr "ხაზის სიგანე (რიცხვი)"
#: tools/gtk-path-tool-render.c:57 tools/gtk-path-tool-show.c:127
msgid "Line cap (butt, round, square)"
msgstr "ხაზის თავი (ისარი, მრგვალი, კვადრატი)"
#: tools/gtk-path-tool-render.c:58 tools/gtk-path-tool-show.c:128
msgid "Line join (miter, miter-clip, round, bevel, arcs)"
msgstr "ხაზების შეერთება (miter, miter-clip, round, bevel, arcs)"
#: tools/gtk-path-tool-render.c:59 tools/gtk-path-tool-show.c:129
msgid "Miter limit (number)"
msgstr "Miter-ის ლიმიტი (რიცხვი)"
#: tools/gtk-path-tool-render.c:60 tools/gtk-path-tool-show.c:130
msgid "Dash pattern (comma-separated numbers)"
msgstr "პუნქტირის ნიმუში (მძიმით გამოყოფილი რიცხვები)"
#: tools/gtk-path-tool-render.c:61 tools/gtk-path-tool-show.c:131
msgid "Dash offset (number)"
msgstr "პუნქტირის წანაცვლება (რიცხვი)"
#: tools/gtk-path-tool-render.c:62
#: tools/gtk-path-tool-render.c:55
msgid "The output file"
msgstr "გამოტანის ფაილი"
#: tools/gtk-path-tool-render.c:81 tools/gtk-path-tool-show.c:145
#: tools/gtk-path-tool-render.c:56 tools/gtk-path-tool-show.c:125
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
msgid "COLOR"
msgstr "ფერი"
#: tools/gtk-path-tool-render.c:57 tools/gtk-path-tool-show.c:126
msgid "Background color"
msgstr "ფონის ფერი"
#: tools/gtk-path-tool-render.c:62 tools/gtk-path-tool-show.c:131
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
msgid "VALUE"
msgstr "მნიშვნელობა"
#: tools/gtk-path-tool-render.c:66 tools/gtk-path-tool-show.c:135
msgid "Line width (number)"
msgstr "ხაზის სიგანე (რიცხვი)"
#: tools/gtk-path-tool-render.c:67 tools/gtk-path-tool-show.c:136
msgid "Line cap (butt, round, square)"
msgstr "ხაზის თავი (ისარი, მრგვალი, კვადრატი)"
#: tools/gtk-path-tool-render.c:68 tools/gtk-path-tool-show.c:137
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
msgid "Miter limit (number)"
msgstr "Miter-ის ლიმიტი (რიცხვი)"
#: tools/gtk-path-tool-render.c:70 tools/gtk-path-tool-show.c:139
msgid "Dash pattern (comma-separated numbers)"
msgstr "პუნქტირის ნიმუში (მძიმით გამოყოფილი რიცხვები)"
#: tools/gtk-path-tool-render.c:71 tools/gtk-path-tool-show.c:140
msgid "Dash offset (number)"
msgstr "პუნქტირის წანაცვლება (რიცხვი)"
#: tools/gtk-path-tool-render.c:90 tools/gtk-path-tool-show.c:153
msgid "Could not initialize windowing system"
msgstr "ფანჯრული სისტემის ინიციალიზაციის შეცდომა"
#: tools/gtk-path-tool-render.c:89
#: tools/gtk-path-tool-render.c:97
msgid "Render the path to a png image."
msgstr "ბილიკის რენდერი png გამოსახულებაში."
#: tools/gtk-path-tool-render.c:102 tools/gtk-path-tool-show.c:166
#: tools/gtk-path-tool-render.c:102 tools/gtk-path-tool-show.c:164
msgid "Options related to filling"
msgstr "შევსების პარამეტრები"
#: tools/gtk-path-tool-render.c:103 tools/gtk-path-tool-show.c:165
msgid "Show help for fill options"
msgstr "დახმარების ჩვენება შევსების პარამეტრებისთვის"
#: tools/gtk-path-tool-render.c:110 tools/gtk-path-tool-show.c:172
msgid "Options related to stroking"
msgstr "სვლის პარამეტრები"
#: tools/gtk-path-tool-render.c:111 tools/gtk-path-tool-show.c:173
msgid "Show help for stroke options"
msgstr "დახმარების ჩვენება სვლის პარამეტრებისთვის"
#: tools/gtk-path-tool-render.c:128 tools/gtk-path-tool-show.c:190
msgid "No path specified"
msgstr "ბილიკი მითითებული არაა"
#: tools/gtk-path-tool-render.c:108
#: tools/gtk-path-tool-render.c:134
msgid "Can only render a single path"
msgstr "შესაძლებელია მხოლოდ ერთ ბილიკის რენდერი"
#: tools/gtk-path-tool-render.c:114 tools/gtk-path-tool-show.c:178
#: tools/gtk-path-tool-render.c:140 tools/gtk-path-tool-show.c:202
msgid "fill rule"
msgstr "შევსების წესი"
#: tools/gtk-path-tool-render.c:118 tools/gtk-path-tool-show.c:182
#: tools/gtk-path-tool-render.c:144 tools/gtk-path-tool-show.c:206
msgid "line cap"
msgstr "ხაზის თავი"
#: tools/gtk-path-tool-render.c:119 tools/gtk-path-tool-show.c:183
#: tools/gtk-path-tool-render.c:145 tools/gtk-path-tool-show.c:207
msgid "line join"
msgstr "ხაზების შეერთება"
#: tools/gtk-path-tool-render.c:143 tools/gtk-path-tool-show.c:207
#: 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:187
#: tools/gtk-path-tool-render.c:213
#, c-format
msgid "Saving png to '%s' failed"
msgstr "PNG-ის '%s'-ში შენახვა შეუძლებელია"
#: tools/gtk-path-tool-render.c:194
#: tools/gtk-path-tool-render.c:220
#, c-format
msgid "Output written to '%s'."
msgstr "გამოტანილი ინფორმაცია ჩაწერილია %s-ში."
@@ -7638,11 +7658,11 @@ msgstr "გამოტანილი ინფორმაცია ჩაწ
msgid "Path Preview"
msgstr "ბილიკის მინიატურა"
#: tools/gtk-path-tool-show.c:153
#: tools/gtk-path-tool-show.c:161
msgid "Display the path."
msgstr "ბილიკის ჩვენება."
#: tools/gtk-path-tool-show.c:172
#: tools/gtk-path-tool-show.c:196
msgid "Can only show a single path"
msgstr "შესაძლებელია მხოლოდ ერთი ბილიკის ჩვენება"
@@ -7889,6 +7909,9 @@ msgstr ""
"თუ მართლა გნებავთ, ხატულების კეში აქ შექმნათ, --ignore-theme-index "
"გამოიყენეთ.\n"
#~ msgid "Stroke the path instead of filling it"
#~ msgstr "ბილიკის შემოვლება მისი შევსების მაგიერ"
#~ msgid "Simulate Touchscreen"
#~ msgstr "სენსორული ეკრანის სიმულაცია"
+91 -71
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-19 01:57+0000\n"
"PO-Revision-Date: 2023-08-19 17:17+0200\n"
"POT-Creation-Date: 2023-08-22 16:19+0000\n"
"PO-Revision-Date: 2023-08-23 16:42+0200\n"
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
"Language-Team: Polish <community-poland@mozilla.org>\n"
"Language: pl\n"
@@ -573,7 +573,7 @@ msgstr "Odczytanie danych nie powiodło się w %d. rzędzie"
#: 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 "Nie odnaleziono zgodnego formatu przesyłania"
@@ -801,11 +801,11 @@ msgstr[0] "Otwieranie %d elementu"
msgstr[1] "Otwieranie %d elementów"
msgstr[2] "Otwieranie %d elementów"
#: gdk/x11/gdkclipboard-x11.c:475
#: gdk/x11/gdkclipboard-x11.c:477
msgid "Clipboard manager could not store selection."
msgstr "Menedżer schowka nie może przechować zaznaczenia."
#: gdk/x11/gdkclipboard-x11.c:655
#: gdk/x11/gdkclipboard-x11.c:657
msgid "Cannot store clipboard. No clipboard manager is active."
msgstr "Nie można przechować schowka. Żaden menedżer schowka nie jest aktywny."
@@ -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:62 tools/gtk-rendernode-tool-info.c:208
#: tools/gtk-path-tool-render.c:55 tools/gtk-rendernode-tool-info.c:208
#: tools/gtk-rendernode-tool-show.c:102
msgid "FILE"
msgstr "PLIK"
@@ -7497,7 +7497,7 @@ 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:63 tools/gtk-path-tool-show.c:132
#: tools/gtk-path-tool-render.c:58 tools/gtk-path-tool-show.c:127
msgid "PATH"
msgstr "ŚCIEŻKA"
@@ -7550,104 +7550,124 @@ msgstr "Równania kwadratowe: %d"
msgid "%d cubics"
msgstr "Równania sześcienne: %d"
#: tools/gtk-path-tool-render.c:52 tools/gtk-path-tool-show.c:122
msgid "Fill rule (winding, even-odd)"
msgstr "Reguła wypełniania (kręcona, parzysta-nieparzysta)"
#: tools/gtk-path-tool-render.c:52 tools/gtk-path-tool-render.c:56
#: tools/gtk-path-tool-render.c:57 tools/gtk-path-tool-render.c:58
#: tools/gtk-path-tool-render.c:59 tools/gtk-path-tool-render.c:60
#: tools/gtk-path-tool-render.c:61 tools/gtk-path-tool-show.c:122
#: tools/gtk-path-tool-show.c:126 tools/gtk-path-tool-show.c:127
#: tools/gtk-path-tool-show.c:128 tools/gtk-path-tool-show.c:129
#: tools/gtk-path-tool-show.c:130 tools/gtk-path-tool-show.c:131
msgid "VALUE"
msgstr "WARTOŚĆ"
#: tools/gtk-path-tool-render.c:53 tools/gtk-path-tool-show.c:123
msgid "Foreground color"
msgstr "Kolor pierwszego planu"
#: tools/gtk-path-tool-render.c:53 tools/gtk-path-tool-render.c:54
#: tools/gtk-path-tool-show.c:123 tools/gtk-path-tool-show.c:124
msgid "COLOR"
msgstr "KOLOR"
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
msgid "Background color"
msgstr "Kolor tła"
msgid "Stroke the path"
msgstr "Pociąga ścieżkę"
#: tools/gtk-path-tool-render.c:55 tools/gtk-path-tool-show.c:125
msgid "Stroke the path instead of filling it"
msgstr "Pociąga ścieżkę zamiast ją wypełniać"
#: tools/gtk-path-tool-render.c:56 tools/gtk-path-tool-show.c:126
msgid "Line width (number)"
msgstr "Szerokość linii (liczba)"
#: tools/gtk-path-tool-render.c:57 tools/gtk-path-tool-show.c:127
msgid "Line cap (butt, round, square)"
msgstr "Koniec linii (grubszy koniec, okrągły, kwadratowy)"
#: tools/gtk-path-tool-render.c:58 tools/gtk-path-tool-show.c:128
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:59 tools/gtk-path-tool-show.c:129
msgid "Miter limit (number)"
msgstr "Ograniczenie kątowych (liczba)"
#: tools/gtk-path-tool-render.c:60 tools/gtk-path-tool-show.c:130
msgid "Dash pattern (comma-separated numbers)"
msgstr "Wzór kresek (liczby oddzielone przecinkami)"
#: tools/gtk-path-tool-render.c:61 tools/gtk-path-tool-show.c:131
msgid "Dash offset (number)"
msgstr "Wyrównanie kresek (liczba)"
#: tools/gtk-path-tool-render.c:62
#: tools/gtk-path-tool-render.c:55
msgid "The output file"
msgstr "Plik wyjściowy"
#: tools/gtk-path-tool-render.c:81 tools/gtk-path-tool-show.c:145
#: tools/gtk-path-tool-render.c:56 tools/gtk-path-tool-show.c:125
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
msgid "COLOR"
msgstr "KOLOR"
#: tools/gtk-path-tool-render.c:57 tools/gtk-path-tool-show.c:126
msgid "Background color"
msgstr "Kolor tła"
#: tools/gtk-path-tool-render.c:62 tools/gtk-path-tool-show.c:131
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
msgid "VALUE"
msgstr "WARTOŚĆ"
#: tools/gtk-path-tool-render.c:66 tools/gtk-path-tool-show.c:135
msgid "Line width (number)"
msgstr "Szerokość linii (liczba)"
#: tools/gtk-path-tool-render.c:67 tools/gtk-path-tool-show.c:136
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
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
msgid "Miter limit (number)"
msgstr "Ograniczenie kątowych (liczba)"
#: tools/gtk-path-tool-render.c:70 tools/gtk-path-tool-show.c:139
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
msgid "Dash offset (number)"
msgstr "Wyrównanie kresek (liczba)"
#: tools/gtk-path-tool-render.c:90 tools/gtk-path-tool-show.c:153
msgid "Could not initialize windowing system"
msgstr "Nie można zainicjować systemu okien"
#: tools/gtk-path-tool-render.c:89
#: tools/gtk-path-tool-render.c:97
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:166
#: tools/gtk-path-tool-render.c:102 tools/gtk-path-tool-show.c:164
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
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
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
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
msgid "No path specified"
msgstr "Nie podano ścieżki"
#: tools/gtk-path-tool-render.c:108
#: tools/gtk-path-tool-render.c:134
msgid "Can only render a single path"
msgstr "Można narysować tylko jedną ścieżkę"
#: tools/gtk-path-tool-render.c:114 tools/gtk-path-tool-show.c:178
#: tools/gtk-path-tool-render.c:140 tools/gtk-path-tool-show.c:202
msgid "fill rule"
msgstr "reguła wypełniania"
#: tools/gtk-path-tool-render.c:118 tools/gtk-path-tool-show.c:182
#: tools/gtk-path-tool-render.c:144 tools/gtk-path-tool-show.c:206
msgid "line cap"
msgstr "koniec linii"
#: tools/gtk-path-tool-render.c:119 tools/gtk-path-tool-show.c:183
#: tools/gtk-path-tool-render.c:145 tools/gtk-path-tool-show.c:207
msgid "line join"
msgstr "złącze linii"
#: tools/gtk-path-tool-render.c:143 tools/gtk-path-tool-show.c:207
#: 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:187
#: tools/gtk-path-tool-render.c:213
#, c-format
msgid "Saving png to '%s' failed"
msgstr "Zapisanie obrazu PNG do „%s” się nie powiodło"
#: tools/gtk-path-tool-render.c:194
#: tools/gtk-path-tool-render.c:220
#, c-format
msgid "Output written to '%s'."
msgstr "Wyjście zapisano do „%s”."
@@ -7656,11 +7676,11 @@ msgstr "Wyjście zapisano do „%s”."
msgid "Path Preview"
msgstr "Podgląd ścieżki"
#: tools/gtk-path-tool-show.c:153
#: tools/gtk-path-tool-show.c:161
msgid "Display the path."
msgstr "Wyświetla ścieżkę."
#: tools/gtk-path-tool-show.c:172
#: tools/gtk-path-tool-show.c:196
msgid "Can only show a single path"
msgstr "Można wyświetlić tylko jedną ścieżkę"
+94 -71
View File
@@ -22,8 +22,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-16 20:40+0000\n"
"PO-Revision-Date: 2023-08-17 21:02+0300\n"
"POT-Creation-Date: 2023-08-22 16:19+0000\n"
"PO-Revision-Date: 2023-08-22 22:19+0300\n"
"Last-Translator: Sabri Ünal <libreajans@gmail.com>\n"
"Language-Team: Türkçe <takim@gnome.org.tr>\n"
"Language: tr\n"
@@ -579,7 +579,7 @@ msgstr "Veri okunurken %d. satırda hata"
#: 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 "Uyumlu aktarım biçimi bulunamadı"
@@ -775,11 +775,11 @@ msgid "Opening %d Item"
msgid_plural "Opening %d Items"
msgstr[0] "%d öge açılıyor"
#: gdk/x11/gdkclipboard-x11.c:475
#: gdk/x11/gdkclipboard-x11.c:477
msgid "Clipboard manager could not store selection."
msgstr "Pano yöneticisi seçimi depolayamadı."
#: gdk/x11/gdkclipboard-x11.c:655
#: gdk/x11/gdkclipboard-x11.c:657
msgid "Cannot store clipboard. No clipboard manager is active."
msgstr "Pano depolanamadı. Aktif pano yöneticisi yok."
@@ -7164,7 +7164,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:62 tools/gtk-rendernode-tool-info.c:208
#: tools/gtk-path-tool-render.c:55 tools/gtk-rendernode-tool-info.c:208
#: tools/gtk-rendernode-tool-show.c:102
msgid "FILE"
msgstr "DOSYA"
@@ -7463,7 +7463,7 @@ msgid "Allow cubic Bézier curves"
msgstr "Kübik Bézier eğrilerine izin ver"
#: tools/gtk-path-tool-decompose.c:77 tools/gtk-path-tool-info.c:88
#: tools/gtk-path-tool-render.c:63 tools/gtk-path-tool-show.c:132
#: tools/gtk-path-tool-render.c:58 tools/gtk-path-tool-show.c:127
msgid "PATH"
msgstr "YOL"
@@ -7516,105 +7516,125 @@ msgstr "%d karesel"
msgid "%d cubics"
msgstr "%d kübik"
#: tools/gtk-path-tool-render.c:52 tools/gtk-path-tool-show.c:122
msgid "Fill rule (winding, even-odd)"
msgstr "Doldurma kuralı (sarma, çift-tek)"
#: tools/gtk-path-tool-render.c:52 tools/gtk-path-tool-render.c:56
#: tools/gtk-path-tool-render.c:57 tools/gtk-path-tool-render.c:58
#: tools/gtk-path-tool-render.c:59 tools/gtk-path-tool-render.c:60
#: tools/gtk-path-tool-render.c:61 tools/gtk-path-tool-show.c:122
#: tools/gtk-path-tool-show.c:126 tools/gtk-path-tool-show.c:127
#: tools/gtk-path-tool-show.c:128 tools/gtk-path-tool-show.c:129
#: tools/gtk-path-tool-show.c:130 tools/gtk-path-tool-show.c:131
msgid "VALUE"
msgstr "DEĞER"
#: tools/gtk-path-tool-render.c:53 tools/gtk-path-tool-show.c:123
msgid "Foreground color"
msgstr "Ön alan rengi"
#: tools/gtk-path-tool-render.c:53 tools/gtk-path-tool-render.c:54
#: tools/gtk-path-tool-show.c:123 tools/gtk-path-tool-show.c:124
msgid "COLOR"
msgstr "RENK"
msgid "Fill the path (the default)"
msgstr "Yolu doldur (öntanımlı)"
#: tools/gtk-path-tool-render.c:54 tools/gtk-path-tool-show.c:124
msgid "Background color"
msgstr "Arka plan rengi"
msgid "Stroke the path"
msgstr "Yolu darbele"
#: tools/gtk-path-tool-render.c:55 tools/gtk-path-tool-show.c:125
msgid "Stroke the path instead of filling it"
msgstr "Doldurmak yerine yolu darbele"
#: tools/gtk-path-tool-render.c:56 tools/gtk-path-tool-show.c:126
msgid "Line width (number)"
msgstr "Çizgi genişliği (sayı)"
#: tools/gtk-path-tool-render.c:57 tools/gtk-path-tool-show.c:127
msgid "Line cap (butt, round, square)"
msgstr "Çizgi ucu (uç, yuvarlak, kare)"
#: tools/gtk-path-tool-render.c:58 tools/gtk-path-tool-show.c:128
msgid "Line join (miter, miter-clip, round, bevel, arcs)"
msgstr "Çizgi birleşimi (gönye, gönye yakalama, yuvarlak, eğim, yay)"
#: tools/gtk-path-tool-render.c:59 tools/gtk-path-tool-show.c:129
msgid "Miter limit (number)"
msgstr "Gönye sınırı (sayı)"
#: tools/gtk-path-tool-render.c:60 tools/gtk-path-tool-show.c:130
msgid "Dash pattern (comma-separated numbers)"
msgstr "Tire deseni (virgülle ayrılmış sayılar)"
#: tools/gtk-path-tool-render.c:61 tools/gtk-path-tool-show.c:131
msgid "Dash offset (number)"
msgstr "Tire konumu (sayı)"
#: tools/gtk-path-tool-render.c:62
#: tools/gtk-path-tool-render.c:55
msgid "The output file"
msgstr "Çıktı dosyası"
#: tools/gtk-path-tool-render.c:81 tools/gtk-path-tool-show.c:145
#: tools/gtk-path-tool-render.c:56 tools/gtk-path-tool-show.c:125
msgid "Foreground color"
msgstr "Ön alan rengi"
#: 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
msgid "COLOR"
msgstr "RENK"
#: tools/gtk-path-tool-render.c:57 tools/gtk-path-tool-show.c:126
msgid "Background color"
msgstr "Arka plan rengi"
#: tools/gtk-path-tool-render.c:62 tools/gtk-path-tool-show.c:131
msgid "Fill rule (winding, even-odd)"
msgstr "Doldurma kuralı (sarma, çift-tek)"
#: 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
msgid "VALUE"
msgstr "DEĞER"
#: tools/gtk-path-tool-render.c:66 tools/gtk-path-tool-show.c:135
msgid "Line width (number)"
msgstr "Çizgi genişliği (sayı)"
#: tools/gtk-path-tool-render.c:67 tools/gtk-path-tool-show.c:136
msgid "Line cap (butt, round, square)"
msgstr "Çizgi ucu (uç, yuvarlak, kare)"
#: tools/gtk-path-tool-render.c:68 tools/gtk-path-tool-show.c:137
msgid "Line join (miter, miter-clip, round, bevel, arcs)"
msgstr "Çizgi birleşimi (gönye, gönye yakalama, yuvarlak, eğim, yay)"
#: tools/gtk-path-tool-render.c:69 tools/gtk-path-tool-show.c:138
msgid "Miter limit (number)"
msgstr "Gönye sınırı (sayı)"
#: tools/gtk-path-tool-render.c:70 tools/gtk-path-tool-show.c:139
msgid "Dash pattern (comma-separated numbers)"
msgstr "Tire deseni (virgülle ayrılmış sayılar)"
#: tools/gtk-path-tool-render.c:71 tools/gtk-path-tool-show.c:140
msgid "Dash offset (number)"
msgstr "Tire konumu (sayı)"
#: tools/gtk-path-tool-render.c:90 tools/gtk-path-tool-show.c:153
msgid "Could not initialize windowing system"
msgstr "Pencereleme sistemi ilklendirilemedi"
#: tools/gtk-path-tool-render.c:89
#: tools/gtk-path-tool-render.c:97
msgid "Render the path to a png image."
msgstr "Yolu png resmine gerçekle."
#: tools/gtk-path-tool-render.c:102 tools/gtk-path-tool-show.c:166
#: tools/gtk-path-tool-render.c:102 tools/gtk-path-tool-show.c:164
msgid "Options related to filling"
msgstr "Doldurmayla ilgili seçenekler"
#: tools/gtk-path-tool-render.c:103 tools/gtk-path-tool-show.c:165
msgid "Show help for fill options"
msgstr "Doldurma seçenekleri için yardım göster"
#: tools/gtk-path-tool-render.c:110 tools/gtk-path-tool-show.c:172
msgid "Options related to stroking"
msgstr "Darbelemeyle ilgili seçenekler"
#: tools/gtk-path-tool-render.c:111 tools/gtk-path-tool-show.c:173
msgid "Show help for stroke options"
msgstr "Darbeleme seçenekleri için yardım göster"
#: tools/gtk-path-tool-render.c:128 tools/gtk-path-tool-show.c:190
msgid "No path specified"
msgstr "Yol belirtilmedi"
# Buradaki --replace yi çevirmedim, çevrilmesi gerekiyor mu bilemedim.
#: tools/gtk-path-tool-render.c:108
#: tools/gtk-path-tool-render.c:134
msgid "Can only render a single path"
msgstr "Yalnızca tek bir yol gerçeklenebilir"
#: tools/gtk-path-tool-render.c:114 tools/gtk-path-tool-show.c:178
#: tools/gtk-path-tool-render.c:140 tools/gtk-path-tool-show.c:202
msgid "fill rule"
msgstr "doldurma kuralı"
#: tools/gtk-path-tool-render.c:118 tools/gtk-path-tool-show.c:182
#: tools/gtk-path-tool-render.c:144 tools/gtk-path-tool-show.c:206
msgid "line cap"
msgstr "çizgi ucu"
#: tools/gtk-path-tool-render.c:119 tools/gtk-path-tool-show.c:183
#: tools/gtk-path-tool-render.c:145 tools/gtk-path-tool-show.c:207
msgid "line join"
msgstr "çizgi birleşimi"
#: tools/gtk-path-tool-render.c:143 tools/gtk-path-tool-show.c:207
#: 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', sayı olarak ayrıştırılamadı"
#: tools/gtk-path-tool-render.c:187
#: tools/gtk-path-tool-render.c:213
#, c-format
msgid "Saving png to '%s' failed"
msgstr "'%s' png kaydı başarısız"
#: tools/gtk-path-tool-render.c:194
#: tools/gtk-path-tool-render.c:220
#, c-format
msgid "Output written to '%s'."
msgstr "Çıktı şuna yazıldı: '%s'."
@@ -7623,12 +7643,12 @@ msgstr "Çıktı şuna yazıldı: '%s'."
msgid "Path Preview"
msgstr "Yol Ön İzlemesi"
#: tools/gtk-path-tool-show.c:153
#: tools/gtk-path-tool-show.c:161
msgid "Display the path."
msgstr "Yolu görüntüle."
# Buradaki --replace yi çevirmedim, çevrilmesi gerekiyor mu bilemedim.
#: tools/gtk-path-tool-show.c:172
#: tools/gtk-path-tool-show.c:196
msgid "Can only show a single path"
msgstr "Yalnızca tek bir yol gösterilebilir"
@@ -7874,3 +7894,6 @@ msgstr ""
"“%s” içinde tema dizin dosyası yok.\n"
"Eğer burada gerçekten bir simge önbelleği oluşturmak istiyorsanız, --ignore-"
"theme-indexʼi kullanın.\n"
#~ msgid "Stroke the path instead of filling it"
#~ msgstr "Doldurmak yerine yolu darbele"
+44
View File
@@ -9,6 +9,10 @@ static gboolean flip = FALSE;
static gboolean rotate = FALSE;
static gboolean repeat = FALSE;
static gboolean mask = FALSE;
static gboolean replay = FALSE;
extern void
replay_node (GskRenderNode *node, GtkSnapshot *snapshot);
static const char *
get_output_dir (void)
@@ -159,6 +163,7 @@ static const GOptionEntry options[] = {
{ "rotate", 0, 0, G_OPTION_ARG_NONE, &rotate, "Do rotated test", NULL },
{ "repeat", 0, 0, G_OPTION_ARG_NONE, &repeat, "Do repeated test", NULL },
{ "mask", 0, 0, G_OPTION_ARG_NONE, &mask, "Do masked test", NULL },
{ "replay", 0, 0, G_OPTION_ARG_NONE, &replay, "Do replay test", NULL },
{ NULL }
};
@@ -487,6 +492,45 @@ main (int argc, char **argv)
gsk_render_node_unref (node2);
}
if (replay)
{
GskRenderNode *node2;
GdkTexture *rendered_texture2;
graphene_rect_t node_bounds, node2_bounds;
GtkSnapshot *snapshot = gtk_snapshot_new ();
replay_node (node, snapshot);
node2 = gtk_snapshot_free_to_node (snapshot);
/* If the whole render node tree got eliminated, make sure we have
something to work with nevertheless. */
if (!node2)
node2 = gsk_container_node_new (NULL, 0);
gsk_render_node_get_bounds (node, &node_bounds);
gsk_render_node_get_bounds (node2, &node2_bounds);
/* Check that the node didn't grow. */
success = success && graphene_rect_contains_rect (&node_bounds, &node2_bounds);
rendered_texture = gsk_renderer_render_texture (renderer, node, &node_bounds);
rendered_texture2 = gsk_renderer_render_texture (renderer, node2, &node_bounds);
g_assert_nonnull (rendered_texture);
g_assert_nonnull (rendered_texture2);
diff_texture = reftest_compare_textures (rendered_texture, rendered_texture2);
if (diff_texture)
{
save_image (diff_texture, node_file, "-replayed.diff.png");
save_node (node2, node_file, "-replayed.node");
g_object_unref (diff_texture);
success = FALSE;
}
g_clear_object (&rendered_texture);
g_clear_object (&rendered_texture2);
gsk_render_node_unref (node2);
}
gsk_render_node_unref (node);
gsk_renderer_unrealize (renderer);
@@ -0,0 +1,17 @@
color-matrix {
matrix: matrix3d(1, 0, 0, 0,
0, 0, 1, 0,
0, 1, 0, 0,
0, 0, 0, 1);
offset: -1 0 1 0;
child: color-matrix {
matrix: matrix3d(0, 1, 0, 0,
1, 0, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
offset: 1 0 0 0;
child: color {
color: red;
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 144 B

+59 -1
View File
@@ -92,6 +92,7 @@ static gboolean
pathop_cb (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer user_data)
{
GskCurve *curve = user_data;
@@ -101,7 +102,7 @@ pathop_cb (GskPathOperation op,
if (op == GSK_PATH_MOVE)
return TRUE;
gsk_curve_init_foreach (curve, op, pts, n_pts);
gsk_curve_init_foreach (curve, op, pts, n_pts, weight);
return FALSE;
}
@@ -145,6 +146,61 @@ test_curve_crossing (void)
}
}
static void
test_circle (void)
{
GskCurve c;
graphene_vec2_t tangent, tangent2;
parse_curve (&c, "M 1 0 O 1 1 0 1 0.707107");
g_assert_true (c.op == GSK_PATH_CONIC);
g_assert_true (graphene_point_equal (gsk_curve_get_start_point (&c), &GRAPHENE_POINT_INIT (1, 0)));
g_assert_true (graphene_point_equal (gsk_curve_get_end_point (&c), &GRAPHENE_POINT_INIT (0, 1)));
gsk_curve_get_start_tangent (&c, &tangent);
g_assert_true (graphene_vec2_equal (&tangent, graphene_vec2_init (&tangent2, 0, 1)));
gsk_curve_get_end_tangent (&c, &tangent);
g_assert_true (graphene_vec2_equal (&tangent, graphene_vec2_init (&tangent2, -1, 0)));
g_assert_cmpfloat_with_epsilon (gsk_curve_get_length (&c), M_PI_2, 0.001);
for (int i = 1; i < 10; i++)
{
float t = i / 10.f;
float dist, t_out;
gsk_curve_get_closest_point (&c,
&GRAPHENE_POINT_INIT (cos (t * M_PI_2),
sin (t * M_PI_2)),
INFINITY,
&dist,
&t_out);
g_assert_true (dist < 0.001);
}
}
static void
test_curve_length (void)
{
GskCurve c, c1, c2;
float l, l1, l2, l1a;
parse_curve (&c, "M 1462.632080 -1593.118896 C 751.533630 -74.179169 -914.280090 956.537720 -83.091866 207.213776");
gsk_curve_split (&c, 0.5, &c1, &c2);
l = gsk_curve_get_length (&c);
l1a = gsk_curve_get_length_to (&c, 0.5);
l1 = gsk_curve_get_length (&c1);
l2 = gsk_curve_get_length (&c2);
g_assert_cmpfloat_with_epsilon (l1, l1a, 0.1);
g_assert_cmpfloat_with_epsilon (l, l1 + l2, 0.5);
}
int
main (int argc,
char *argv[])
@@ -154,6 +210,8 @@ main (int argc,
g_test_add_func ("/curve/special/tangents", test_curve_tangents);
g_test_add_func ("/curve/special/degenerate-tangents", test_curve_degenerate_tangents);
g_test_add_func ("/curve/special/crossing", test_curve_crossing);
g_test_add_func ("/curve/special/circle", test_circle);
g_test_add_func ("/curve/special/length", test_curve_length);
return g_test_run ();
}
+117 -38
View File
@@ -48,6 +48,19 @@ init_random_curve_with_op (GskCurve *curve,
}
break;
case GSK_PATH_CONIC:
{
graphene_point_t p[4];
init_random_point (&p[0]);
init_random_point (&p[1]);
p[2].x = g_test_rand_double_range (0.2, 20);
p[2].y = 0.f;
init_random_point (&p[3]);
gsk_curve_init (curve, gsk_pathop_encode (GSK_PATH_CONIC, p));
}
break;
default:
g_assert_not_reached ();
}
@@ -56,7 +69,7 @@ init_random_curve_with_op (GskCurve *curve,
static void
init_random_curve (GskCurve *curve)
{
init_random_curve_with_op (curve, GSK_PATH_LINE, GSK_PATH_CUBIC);
init_random_curve_with_op (curve, GSK_PATH_LINE, GSK_PATH_CONIC);
}
static void
@@ -93,11 +106,13 @@ test_curve_points (void)
init_random_curve (&c);
/* We can assert equality here because evaluating the polynomials with 0
* has no effect on accuracy.
/* We could assert equality here because evaluating the polynomials with 0
* has no effect on accuracy, but for arcs, we use trigonometric functions,
* so allow a small error.
*/
gsk_curve_get_point (&c, 0, &p);
g_assert_true (graphene_point_equal (gsk_curve_get_start_point (&c), &p));
g_assert_true (graphene_point_near (gsk_curve_get_start_point (&c), &p, 0.001));
/* But here we evaluate the polynomials with 1 which gives the highest possible
* accuracy error. So we'll just be generous here.
*/
@@ -182,8 +197,8 @@ test_curve_decompose (void)
gsk_curve_get_point (&c, (pol->t + last->t) / 2, &p);
/* The decomposer does this cheaper Manhattan distance test,
* so graphene_point_near() does not work */
g_assert_cmpfloat (fabs (mid.x - p.x), <=, tolerance);
g_assert_cmpfloat (fabs (mid.y - p.y), <=, tolerance);
g_assert_cmpfloat (fabs (mid.x - p.x), <=, tolerance + 0.0002);
g_assert_cmpfloat (fabs (mid.y - p.y), <=, tolerance + 0.0002);
}
}
}
@@ -196,12 +211,13 @@ static gboolean
add_curve_to_array (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer user_data)
{
GArray *array = user_data;
GskCurve c;
gsk_curve_init_foreach (&c, op, pts, n_pts);
gsk_curve_init_foreach (&c, op, pts, n_pts, weight);
g_array_append_val (array, c);
return TRUE;
@@ -249,6 +265,9 @@ test_curve_decompose_into (GskPathForeachFlags flags)
case GSK_PATH_CUBIC:
g_assert_true (flags & GSK_PATH_FOREACH_ALLOW_CUBIC);
break;
case GSK_PATH_CONIC:
g_assert_true (flags & GSK_PATH_FOREACH_ALLOW_CONIC);
break;
default:
g_assert_not_reached ();
}
@@ -281,42 +300,100 @@ test_curve_decompose_into_cubic (void)
static void
test_curve_split (void)
{
for (int i = 0; i < 100; i++)
for (int i = 0; i < 20; i++)
{
GskCurve c;
GskCurve c1, c2;
graphene_point_t p;
graphene_vec2_t t, t1, t2;
init_random_curve (&c);
gsk_curve_split (&c, 0.5, &c1, &c2);
for (int j = 0; j < 20; j++)
{
GskCurve c1, c2;
graphene_point_t p;
graphene_vec2_t t, t1, t2;
float split;
g_assert_true (c1.op == c.op);
g_assert_true (c2.op == c.op);
split = g_test_rand_double_range (0.1, 0.9);
g_assert_true (graphene_point_near (gsk_curve_get_start_point (&c),
gsk_curve_get_start_point (&c1), 0.005));
g_assert_true (graphene_point_near (gsk_curve_get_end_point (&c1),
gsk_curve_get_start_point (&c2), 0.005));
g_assert_true (graphene_point_near (gsk_curve_get_end_point (&c),
gsk_curve_get_end_point (&c2), 0.005));
gsk_curve_get_point (&c, 0.5, &p);
gsk_curve_get_tangent (&c, 0.5, &t);
g_assert_true (graphene_point_near (gsk_curve_get_end_point (&c1), &p, 0.005));
g_assert_true (graphene_point_near (gsk_curve_get_start_point (&c2), &p, 0.005));
gsk_curve_split (&c, split, &c1, &c2);
gsk_curve_get_start_tangent (&c, &t1);
gsk_curve_get_start_tangent (&c1, &t2);
g_assert_true (graphene_vec2_near (&t1, &t2, 0.005));
gsk_curve_get_end_tangent (&c1, &t1);
gsk_curve_get_start_tangent (&c2, &t2);
g_assert_true (graphene_vec2_near (&t1, &t2, 0.005));
g_assert_true (graphene_vec2_near (&t, &t1, 0.005));
g_assert_true (graphene_vec2_near (&t, &t2, 0.005));
gsk_curve_get_end_tangent (&c, &t1);
gsk_curve_get_end_tangent (&c2, &t2);
g_assert_true (graphene_vec2_near (&t1, &t2, 0.005));
g_assert_true (c1.op == c.op);
g_assert_true (c2.op == c.op);
g_assert_true (graphene_point_near (gsk_curve_get_start_point (&c),
gsk_curve_get_start_point (&c1), 0.005));
g_assert_true (graphene_point_near (gsk_curve_get_end_point (&c1),
gsk_curve_get_start_point (&c2), 0.005));
g_assert_true (graphene_point_near (gsk_curve_get_end_point (&c),
gsk_curve_get_end_point (&c2), 0.005));
gsk_curve_get_point (&c, split, &p);
gsk_curve_get_tangent (&c, split, &t);
g_assert_true (graphene_point_near (gsk_curve_get_end_point (&c1), &p, 0.005));
g_assert_true (graphene_point_near (gsk_curve_get_start_point (&c2), &p, 0.005));
gsk_curve_get_start_tangent (&c, &t1);
gsk_curve_get_start_tangent (&c1, &t2);
g_assert_true (graphene_vec2_near (&t1, &t2, 0.005));
gsk_curve_get_end_tangent (&c1, &t1);
gsk_curve_get_start_tangent (&c2, &t2);
g_assert_true (graphene_vec2_near (&t1, &t2, 0.005));
g_assert_true (graphene_vec2_near (&t, &t1, 0.005));
g_assert_true (graphene_vec2_near (&t, &t2, 0.005));
gsk_curve_get_end_tangent (&c, &t1);
gsk_curve_get_end_tangent (&c2, &t2);
g_assert_true (graphene_vec2_near (&t1, &t2, 0.005));
#if 0
/* hard to guarantee this for totally random random curves */
g_assert_cmpfloat_with_epsilon (gsk_curve_get_length (&c),
gsk_curve_get_length (&c1) + gsk_curve_get_length (&c2),
1);
#endif
}
}
}
static void
test_curve_derivative (void)
{
GskCurve c;
float t;
graphene_vec2_t t1, t2;
graphene_point_t p;
for (int i = 0; i < 100; i++)
{
init_random_curve (&c);
for (int j = 0; j < 100; j++)
{
t = g_test_rand_double_range (0, 1);
gsk_curve_get_derivative_at (&c, t, &p);
gsk_curve_get_tangent (&c, t, &t1);
graphene_vec2_init (&t2, p.x, p.y);
graphene_vec2_normalize (&t2, &t2);
g_assert_true (graphene_vec2_near (&t1, &t2, 0.1));
}
}
}
static void
test_curve_length (void)
{
GskCurve c;
float l, l0;
for (int i = 0; i < 1000; i++)
{
init_random_curve (&c);
l = gsk_curve_get_length (&c);
l0 = graphene_point_distance (gsk_curve_get_start_point (&c),
gsk_curve_get_end_point (&c),
NULL, NULL);
g_assert_true (l >= l0 - 0.001);
if (c.op == GSK_PATH_LINE)
g_assert_cmpfloat_with_epsilon (l, l0, 0.001);
}
}
@@ -328,10 +405,12 @@ main (int argc, char *argv[])
g_test_add_func ("/curve/points", test_curve_points);
g_test_add_func ("/curve/tangents", test_curve_tangents);
g_test_add_func ("/curve/decompose", test_curve_decompose);
g_test_add_func ("/curve/decompose/into/line", test_curve_decompose_into_line);
g_test_add_func ("/curve/decompose/into/quad", test_curve_decompose_into_quad);
g_test_add_func ("/curve/decompose/into/cubic", test_curve_decompose_into_cubic);
g_test_add_func ("/curve/decompose-line", test_curve_decompose_into_line);
g_test_add_func ("/curve/decompose-quad", test_curve_decompose_into_quad);
g_test_add_func ("/curve/decompose-cubic", test_curve_decompose_into_cubic);
g_test_add_func ("/curve/split", test_curve_split);
g_test_add_func ("/curve/derivative", test_curve_derivative);
g_test_add_func ("/curve/length", test_curve_length);
return g_test_run ();
}
+26 -31
View File
@@ -1,5 +1,5 @@
compare_render = executable('compare-render',
['compare-render.c', '../reftests/reftest-compare.c'],
['compare-render.c', '../reftests/reftest-compare.c', 'replay-node.c'],
dependencies: libgtk_dep,
c_args: common_cflags,
)
@@ -34,6 +34,7 @@ compare_render_tests = [
'clip-translate-offscreen',
'color-blur0',
'color-matrix-identity',
'color-matrix-merge',
'color-matrix-parsing',
'crossfade-clip-both-children',
'cross-fade-in-opacity',
@@ -148,6 +149,13 @@ foreach renderer : renderers
suites += 'wayland_gles_failing'
endif
test_env = [
'GSK_RENDERER=' + renderer_name,
'GTK_A11Y=test',
'G_TEST_SRCDIR=@0@'.format(meson.current_source_dir()),
'G_TEST_BUILDDIR=@0@'.format(meson.current_build_dir())
]
if ((exclude_term == '' or not testname.contains(exclude_term)) and
(renderer_name != 'broadway' or broadway_enabled))
test(renderer_name + ' ' + testname, compare_render,
@@ -156,12 +164,7 @@ foreach renderer : renderers
join_paths(meson.current_source_dir(), 'compare', testname + '.node'),
join_paths(meson.current_source_dir(), 'compare', testname + '.png'),
],
env: [
'GSK_RENDERER=' + renderer_name,
'GTK_A11Y=test',
'G_TEST_SRCDIR=@0@'.format(meson.current_source_dir()),
'G_TEST_BUILDDIR=@0@'.format(meson.current_build_dir())
],
env: test_env,
suite: suites,
)
test(renderer_name + ' ' + testname + ' flipped', compare_render,
@@ -171,12 +174,7 @@ foreach renderer : renderers
join_paths(meson.current_source_dir(), 'compare', testname + '.node'),
join_paths(meson.current_source_dir(), 'compare', testname + '.png'),
],
env: [
'GSK_RENDERER=' + renderer_name,
'GTK_A11Y=test',
'G_TEST_SRCDIR=@0@'.format(meson.current_source_dir()),
'G_TEST_BUILDDIR=@0@'.format(meson.current_build_dir())
],
env: test_env,
suite: suites + [ 'gsk-compare-flipped-' + renderer_name ],
)
test(renderer_name + ' ' + testname + ' repeated', compare_render,
@@ -186,12 +184,7 @@ foreach renderer : renderers
join_paths(meson.current_source_dir(), 'compare', testname + '.node'),
join_paths(meson.current_source_dir(), 'compare', testname + '.png'),
],
env: [
'GSK_RENDERER=' + renderer_name,
'GTK_A11Y=test',
'G_TEST_SRCDIR=@0@'.format(meson.current_source_dir()),
'G_TEST_BUILDDIR=@0@'.format(meson.current_build_dir())
],
env: test_env,
suite: suites + [ 'gsk-compare-repeated-' + renderer_name ],
)
test(renderer_name + ' ' + testname + ' rotated', compare_render,
@@ -201,12 +194,7 @@ foreach renderer : renderers
join_paths(meson.current_source_dir(), 'compare', testname + '.node'),
join_paths(meson.current_source_dir(), 'compare', testname + '.png'),
],
env: [
'GSK_RENDERER=' + renderer_name,
'GTK_A11Y=test',
'G_TEST_SRCDIR=@0@'.format(meson.current_source_dir()),
'G_TEST_BUILDDIR=@0@'.format(meson.current_build_dir())
],
env: test_env,
suite: suites + [ 'gsk-compare-rotated-' + renderer_name ],
)
test(renderer_name + ' ' + testname + ' masked', compare_render,
@@ -216,14 +204,19 @@ foreach renderer : renderers
join_paths(meson.current_source_dir(), 'compare', testname + '.node'),
join_paths(meson.current_source_dir(), 'compare', testname + '.png'),
],
env: [
'GSK_RENDERER=' + renderer_name,
'GTK_A11Y=test',
'G_TEST_SRCDIR=@0@'.format(meson.current_source_dir()),
'G_TEST_BUILDDIR=@0@'.format(meson.current_build_dir())
],
env: test_env,
suite: suites + [ 'gsk-compare-masked-' + renderer_name ],
)
test(renderer_name + ' ' + testname + ' replayed', compare_render,
args: [
'--replay',
'--output', join_paths(meson.current_build_dir(), 'compare', renderer_name),
join_paths(meson.current_source_dir(), 'compare', testname + '.node'),
join_paths(meson.current_source_dir(), 'compare', testname + '.png'),
],
env: test_env,
suite: suites + [ 'gsk-compare-replayed-' + renderer_name ],
)
endif
endforeach
endforeach
@@ -302,6 +295,8 @@ node_parser_tests = [
'empty-transform.ref.node',
'fill.node',
'fill.ref.node',
'fill2.node',
'fill2.ref.node',
'glshader.node',
'glshader.ref.node',
'glshader.errors',
+1 -1
View File
@@ -1,6 +1,6 @@
fill {
child: color {
bounds: 0 0 50 50;
bounds: 1.22359 0 47.5528 45.2254;
color: rgb(255,0,204);
}
path: "\
@@ -1,6 +1,6 @@
stroke {
child: color {
bounds: 0 0 50 50;
bounds: -2.77641 -4 55.5528 53.2254;
color: rgb(255,0,204);
}
path: "\
+4
View File
@@ -0,0 +1,4 @@
fill {
path: "M 0 0 O 10 10 20 20 5";
fill-rule: even-odd;
}
+9
View File
@@ -0,0 +1,9 @@
fill {
child: color {
bounds: 0 0 20 20;
color: rgb(255,0,204);
}
path: "\
M 0 0 O 10 10, 20 20, 5";
fill-rule: even-odd;
}
+10
View File
@@ -0,0 +1,10 @@
stroke {
child: color { bounds: 0 0 100 100; color: red; }
path: "M 10, 10 L 90, 90 M 90, 10 L 10, 90";
line-width: 2.5;
line-cap: butt;
line-join: miter;
miter-limit: 3.1;
dash: 0 1 4.5 10;
dash-offset: 2.1;
}
+17
View File
@@ -0,0 +1,17 @@
stroke {
child: color {
bounds: 0 0 100 100;
color: rgb(255,0,0);
}
path: "\
M 10 10\
L 90 90\
M 90 10\
L 10 90";
line-width: 2.5;
line-cap: butt;
line-join: miter;
miter-limit: 3.1;
dash: 0 1 4.5 10;
dash-offset: 2.1;
}
+191 -1
View File
@@ -342,6 +342,7 @@ static gboolean
collect_path (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer user_data)
{
GskPathBuilder *builder = user_data;
@@ -373,6 +374,12 @@ collect_path (GskPathOperation op,
pts[3].x, pts[3].y);
break;
case GSK_PATH_CONIC:
gsk_path_builder_conic_to (builder, pts[1].x, pts[1].y,
pts[2].x, pts[2].y,
weight);
break;
default:
g_assert_not_reached ();
}
@@ -468,7 +475,7 @@ test_path_point (void)
gsk_path_point_get_position (&point, path, &pos);
gsk_path_point_get_tangent (&point, path, GSK_PATH_FROM_START, &t1);
gsk_path_point_get_tangent (&point, path, GSK_PATH_TO_END, &t2);
curvature = gsk_path_point_get_curvature (&point, path, &center);
curvature = gsk_path_point_get_curvature (&point, path, GSK_PATH_FROM_START, &center);
g_assert_true (graphene_point_equal (&pos, &GRAPHENE_POINT_INIT (100, 100)));
g_assert_true (graphene_vec2_equal (&t1, graphene_vec2_y_axis ()));
@@ -689,6 +696,185 @@ test_path_builder_add (void)
gsk_path_unref (path);
}
static gboolean
rotate_path_cb (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer user_data)
{
GskPathBuilder **builders = user_data;
switch (op)
{
case GSK_PATH_MOVE:
gsk_path_builder_move_to (builders[0], pts[0].x, pts[0].y);
gsk_path_builder_move_to (builders[1], pts[0].y, -pts[0].x);
break;
case GSK_PATH_CLOSE:
gsk_path_builder_close (builders[0]);
gsk_path_builder_close (builders[1]);
break;
case GSK_PATH_LINE:
gsk_path_builder_line_to (builders[0], pts[1].x, pts[1].y);
gsk_path_builder_line_to (builders[1], pts[1].y, -pts[1].x);
break;
case GSK_PATH_QUAD:
gsk_path_builder_quad_to (builders[0], pts[1].x, pts[1].y, pts[2].x, pts[2].y);
gsk_path_builder_quad_to (builders[1], pts[1].y, -pts[1].x, pts[2].y, -pts[2].x);
break;
case GSK_PATH_CUBIC:
gsk_path_builder_cubic_to (builders[0], pts[1].x, pts[1].y, pts[2].x, pts[2].y, pts[3].x, pts[3].y);
gsk_path_builder_cubic_to (builders[1], pts[1].y, -pts[1].x, pts[2].y, -pts[2].x, pts[3].y, -pts[3].x);
break;
case GSK_PATH_CONIC:
gsk_path_builder_conic_to (builders[0], pts[1].x, pts[1].y, pts[2].x, pts[2].y, weight);
gsk_path_builder_conic_to (builders[1], pts[1].y, -pts[1].x, pts[2].y, -pts[2].x, weight);
break;
default:
g_assert_not_reached ();
return FALSE;
}
return TRUE;
}
static void
test_rotated_arc (void)
{
GskPath *path;
GskPathBuilder *builders[2];
GskPath *paths[2];
float x, y;
GskFillRule fill_rule;
path = gsk_path_parse ("M -963 186 O -375 -757, 537 -607 0.707");
x = -626;
y = -274;
builders[0] = gsk_path_builder_new ();
builders[1] = gsk_path_builder_new ();
/* Use -1 here because we want all the flags, even future additions */
gsk_path_foreach (path, -1, rotate_path_cb, builders);
gsk_path_unref (path);
paths[0] = gsk_path_builder_free_to_path (builders[0]);
paths[1] = gsk_path_builder_free_to_path (builders[1]);
fill_rule = GSK_FILL_RULE_EVEN_ODD;
g_assert_true (gsk_path_in_fill (paths[0], &GRAPHENE_POINT_INIT (x, y), fill_rule)
==
gsk_path_in_fill (paths[1], &GRAPHENE_POINT_INIT (y, -x), fill_rule));
gsk_path_unref (paths[0]);
gsk_path_unref (paths[1]);
}
static void
test_rounded_rect (void)
{
GskRoundedRect rect;
GskPathBuilder *builder;
GskPath *path;
gsk_rounded_rect_init (&rect, &GRAPHENE_RECT_INIT (10, 10, 100, 50),
&GRAPHENE_SIZE_INIT (0, 0),
&GRAPHENE_SIZE_INIT (10, 10),
&GRAPHENE_SIZE_INIT (10, 30),
&GRAPHENE_SIZE_INIT (30, 0));
builder = gsk_path_builder_new ();
gsk_path_builder_add_rounded_rect (builder, &rect);
path = gsk_path_builder_free_to_path (builder);
for (int i = 0; i < 1000; i++)
{
graphene_point_t p = GRAPHENE_POINT_INIT (g_test_rand_double_range (0, 200),
g_test_rand_double_range (0, 200));
g_assert_true (gsk_rounded_rect_contains_point (&rect, &p) == gsk_path_in_fill (path, &p, GSK_FILL_RULE_WINDING));
}
gsk_path_unref (path);
}
static void
test_circle (void)
{
GskPathBuilder *builder;
GskPath *path;
GskPathMeasure *measure;
float length;
builder = gsk_path_builder_new ();
gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (0, 0), 1);
path = gsk_path_builder_free_to_path (builder);
measure = gsk_path_measure_new (path);
length = gsk_path_measure_get_length (measure);
g_assert_cmpfloat_with_epsilon (length, 2 * M_PI, 0.001);
gsk_path_measure_unref (measure);
gsk_path_unref (path);
}
static void
test_length (void)
{
GskPath *path, *path1, *path2;
GskPathMeasure *measure, *measure1, *measure2;
GskPathBuilder *builder;
GskPathPoint point, start, end;
float length, length1, length2;
float distance;
float tolerance = 0.1;
path = gsk_path_parse ("M 0 0 Q 0 0 5 5");
measure = gsk_path_measure_new_with_tolerance (path, tolerance);
length = gsk_path_measure_get_length (measure);
gsk_path_get_start_point (path, &start);
gsk_path_get_end_point (path, &end);
gsk_path_measure_get_point (measure, length / 2, &point);
distance = gsk_path_point_get_distance (&point, measure);
g_assert_cmpfloat_with_epsilon (length / 2, distance, 0.1);
builder = gsk_path_builder_new ();
gsk_path_builder_add_segment (builder, path, &start, &point);
path1 = gsk_path_builder_free_to_path (builder);
measure1 = gsk_path_measure_new_with_tolerance (path1, tolerance);
length1 = gsk_path_measure_get_length (measure1);
builder = gsk_path_builder_new ();
gsk_path_builder_add_segment (builder, path, &point, &end);
path2 = gsk_path_builder_free_to_path (builder);
measure2 = gsk_path_measure_new_with_tolerance (path2, tolerance);
length2 = gsk_path_measure_get_length (measure2);
g_assert_cmpfloat_with_epsilon (length, length1 + length2, tolerance);
gsk_path_unref (path);
gsk_path_unref (path1);
gsk_path_unref (path2);
gsk_path_measure_unref (measure);
gsk_path_measure_unref (measure1);
gsk_path_measure_unref (measure2);
}
int
main (int argc, char *argv[])
{
@@ -703,6 +889,10 @@ main (int argc, char *argv[])
g_test_add_func ("/path/bad-in-fill", test_bad_in_fill);
g_test_add_func ("/path/unclosed-in-fill", test_unclosed_in_fill);
g_test_add_func ("/path/builder/add", test_path_builder_add);
g_test_add_func ("/path/rotated-arc", test_rotated_arc);
g_test_add_func ("/path/rounded-rect", test_rounded_rect);
g_test_add_func ("/path/circle", test_circle);
g_test_add_func ("/path/length", test_length);
return g_test_run ();
}
+236 -2
View File
@@ -225,7 +225,7 @@ add_standard_contour (GskPathBuilder *builder)
n = g_test_rand_int_range (1, 20);
for (i = 0; i < n; i++)
{
switch (g_test_rand_int_range (0, 6))
switch (g_test_rand_int_range (0, 8))
{
case 0:
gsk_path_builder_line_to (builder,
@@ -275,6 +275,24 @@ add_standard_contour (GskPathBuilder *builder)
g_test_rand_double_range (-1000, 1000));
break;
case 6:
gsk_path_builder_conic_to (builder,
g_test_rand_double_range (-1000, 1000),
g_test_rand_double_range (-1000, 1000),
g_test_rand_double_range (-1000, 1000),
g_test_rand_double_range (-1000, 1000),
g_test_rand_double_range (0.2, 20));
break;
case 7:
gsk_path_builder_rel_conic_to (builder,
g_test_rand_double_range (-1000, 1000),
g_test_rand_double_range (-1000, 1000),
g_test_rand_double_range (-1000, 1000),
g_test_rand_double_range (-1000, 1000),
g_test_rand_double_range (0.2, 20));
break;
default:
g_assert_not_reached();
break;
@@ -371,6 +389,15 @@ path_operation_print (const PathOperation *p,
_g_string_append_point (string, &p->pts[3]);
break;
case GSK_PATH_CONIC:
g_string_append (string, " O ");
_g_string_append_point (string, &p->pts[1]);
g_string_append (string, ", ");
_g_string_append_point (string, &p->pts[3]);
g_string_append (string, ", ");
_g_string_append_double (string, p->pts[2].x);
break;
default:
g_assert_not_reached();
return;
@@ -405,6 +432,10 @@ path_operation_equal (const PathOperation *p1,
&& graphene_point_near (&p1->pts[2], &p2->pts[2], epsilon)
&& graphene_point_near (&p1->pts[3], &p2->pts[3], epsilon);
case GSK_PATH_CONIC:
return graphene_point_near (&p1->pts[1], &p2->pts[1], epsilon)
&& graphene_point_near (&p1->pts[3], &p2->pts[3], epsilon);
default:
g_return_val_if_reached (FALSE);
}
@@ -414,6 +445,7 @@ static gboolean
collect_path_operation_cb (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer user_data)
{
g_array_append_vals (user_data,
@@ -658,6 +690,7 @@ static gboolean
rotate_path_cb (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer user_data)
{
GskPathBuilder **builders = user_data;
@@ -689,6 +722,11 @@ rotate_path_cb (GskPathOperation op,
gsk_path_builder_cubic_to (builders[1], pts[1].y, -pts[1].x, pts[2].y, -pts[2].x, pts[3].y, -pts[3].x);
break;
case GSK_PATH_CONIC:
gsk_path_builder_conic_to (builders[0], pts[1].x, pts[1].y, pts[2].x, pts[2].y, weight);
gsk_path_builder_conic_to (builders[1], pts[1].y, -pts[1].x, pts[2].y, -pts[2].x, weight);
break;
default:
g_assert_not_reached ();
return FALSE;
@@ -727,7 +765,7 @@ test_in_fill_rotated (void)
GskFillRule fill_rule = g_random_int_range (0, N_FILL_RULES);
float x = g_test_rand_double_range (-1000, 1000);
float y = g_test_rand_double_range (-1000, 1000);
g_assert_cmpint (gsk_path_in_fill (paths[0], &GRAPHENE_POINT_INIT (x, y), fill_rule),
==,
gsk_path_in_fill (paths[1], &GRAPHENE_POINT_INIT (y, -x), fill_rule));
@@ -742,6 +780,199 @@ test_in_fill_rotated (void)
#undef N_FILL_RULES
}
static void
test_split (void)
{
GskPath *path, *path1, *path2;
GskPathMeasure *measure, *measure1, *measure2;
float length, length1, length2;
GskPathBuilder *builder;
float split, epsilon;
GskPathPoint point0, point1, point2;
float tolerance = 0.5;
for (int i = 0; i < 100; i++)
{
if (g_test_verbose ())
g_test_message ("path %u", i);
path = create_random_path (1);
measure = gsk_path_measure_new_with_tolerance (path, tolerance);
length = gsk_path_measure_get_length (measure);
/* chosen high enough to stop the testsuite from failing */
epsilon = MAX (length / 1000, 1.f / 1024);
split = g_test_rand_double_range (0, length);
if (!gsk_path_get_start_point (path, &point0) ||
!gsk_path_measure_get_point (measure, split, &point1) ||
!gsk_path_get_end_point (path, &point2))
{
gsk_path_unref (path);
gsk_path_measure_unref (measure);
continue;
}
if (gsk_path_point_equal (&point0, &point1) ||
gsk_path_point_equal (&point1, &point2))
{
gsk_path_unref (path);
gsk_path_measure_unref (measure);
continue;
}
g_assert_true (gsk_path_point_compare (&point0, &point1) < 0);
g_assert_true (gsk_path_point_compare (&point1, &point2) < 0);
builder = gsk_path_builder_new ();
gsk_path_builder_add_segment (builder, path, &point0, &point1);
path1 = gsk_path_builder_free_to_path (builder);
measure1 = gsk_path_measure_new_with_tolerance (path1, tolerance);
length1 = gsk_path_measure_get_length (measure1);
builder = gsk_path_builder_new ();
gsk_path_builder_add_segment (builder, path, &point1, &point2);
path2 = gsk_path_builder_free_to_path (builder);
measure2 = gsk_path_measure_new_with_tolerance (path2, tolerance);
length2 = gsk_path_measure_get_length (measure2);
g_assert_cmpfloat_with_epsilon (length, length1 + length2, epsilon);
gsk_path_unref (path2);
gsk_path_unref (path1);
gsk_path_unref (path);
gsk_path_measure_unref (measure2);
gsk_path_measure_unref (measure1);
gsk_path_measure_unref (measure);
}
}
static void
test_roundtrip (void)
{
GskPath *path;
GskPathMeasure *measure;
float length;
float split, epsilon;
GskPathPoint point;
float distance;
float tolerance = 0.5;
for (int i = 0; i < 100; i++)
{
if (g_test_verbose ())
g_test_message ("path %u", i);
path = create_random_path (1);
measure = gsk_path_measure_new_with_tolerance (path, tolerance);
length = gsk_path_measure_get_length (measure);
/* chosen high enough to stop the testsuite from failing */
epsilon = MAX (length / 1000, 1.f / 1024);
split = g_test_rand_double_range (0, length);
if (!gsk_path_measure_get_point (measure, split, &point))
{
gsk_path_unref (path);
gsk_path_measure_unref (measure);
continue;
}
distance = gsk_path_point_get_distance (&point, measure);
g_assert_cmpfloat_with_epsilon (split, distance, epsilon);
gsk_path_unref (path);
gsk_path_measure_unref (measure);
}
}
static void
test_segment (void)
{
GskPath *path, *path1, *path2, *path3;
GskPathMeasure *measure, *measure1, *measure2, *measure3;
GskPathPoint point0, point1, point2, point3;
float length, length1, length2, length3;
GskPathBuilder *builder;
float split1, split2, epsilon;
float tolerance = 0.5;
for (int i = 0; i < 100; i++)
{
if (g_test_verbose ())
g_test_message ("path %u", i);
path = create_random_path (G_MAXUINT);
measure = gsk_path_measure_new_with_tolerance (path, tolerance);
length = gsk_path_measure_get_length (measure);
/* We are accumulating both the split error and the roundtrip error
* here (on both ends, for the middle segment). So we should expect
* the epsilon here to be at least 4 times the epsilon we can use
* in the split and roundtrip tests.
*/
epsilon = MAX (length / 200, 1.f / 1024);
split1 = g_test_rand_double_range (0, length);
split2 = g_test_rand_double_range (split1, length);
if (!gsk_path_get_start_point (path, &point0) ||
!gsk_path_measure_get_point (measure, split1, &point1) ||
!gsk_path_measure_get_point (measure, split2, &point2) ||
!gsk_path_get_end_point (path, &point3))
{
gsk_path_unref (path);
gsk_path_measure_unref (measure);
continue;
}
if (gsk_path_point_equal (&point0, &point1) ||
gsk_path_point_equal (&point1, &point2) ||
gsk_path_point_equal (&point2, &point3))
{
gsk_path_unref (path);
gsk_path_measure_unref (measure);
continue;
}
builder = gsk_path_builder_new ();
gsk_path_builder_add_segment (builder, path, &point0, &point1);
path1 = gsk_path_builder_free_to_path (builder);
measure1 = gsk_path_measure_new_with_tolerance (path1, tolerance);
length1 = gsk_path_measure_get_length (measure1);
builder = gsk_path_builder_new ();
gsk_path_builder_add_segment (builder, path, &point1, &point2);
path2 = gsk_path_builder_free_to_path (builder);
measure2 = gsk_path_measure_new_with_tolerance (path2, tolerance);
length2 = gsk_path_measure_get_length (measure2);
builder = gsk_path_builder_new ();
gsk_path_builder_add_segment (builder, path, &point2, &point3);
path3 = gsk_path_builder_free_to_path (builder);
measure3 = gsk_path_measure_new_with_tolerance (path3, tolerance);
length3 = gsk_path_measure_get_length (measure3);
g_assert_cmpfloat_with_epsilon (split1, length1, epsilon);
g_assert_cmpfloat_with_epsilon (split2, length1 + length2, epsilon);
g_assert_cmpfloat_with_epsilon (length, length1 + length2 + length3, epsilon);
gsk_path_unref (path3);
gsk_path_unref (path2);
gsk_path_unref (path1);
gsk_path_unref (path);
gsk_path_measure_unref (measure3);
gsk_path_measure_unref (measure2);
gsk_path_measure_unref (measure1);
gsk_path_measure_unref (measure);
}
}
int
main (int argc,
char *argv[])
@@ -752,6 +983,9 @@ main (int argc,
g_test_add_func ("/path/parse", test_parse);
g_test_add_func ("/path/in-fill-union", test_in_fill_union);
g_test_add_func ("/path/in-fill-rotated", test_in_fill_rotated);
g_test_add_func ("/path/measure/split", test_split);
g_test_add_func ("/path/measure/roundtrip", test_roundtrip);
g_test_add_func ("/path/measure/segment", test_segment);
return g_test_run ();
}

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