Compare commits
241 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e04cdce680 | |||
| 812b30eb54 | |||
| 2b5ec9e879 | |||
| c18a7ff5cf | |||
| 24fc38b287 | |||
| aa03c50f05 | |||
| 03e971b2e3 | |||
| a595133b77 | |||
| e50f4ecccf | |||
| 67913e4af0 | |||
| b3d1795327 | |||
| 6edcc8f256 | |||
| d5e5f47666 | |||
| 0524c40640 | |||
| b5fd894f77 | |||
| d8492121aa | |||
| 4a0bf603d7 | |||
| 02fa89df9e | |||
| 5b6dde9a73 | |||
| e9d8ebdfc9 | |||
| 366efc3d61 | |||
| 3b890fd3c1 | |||
| 5de373a14b | |||
| 24cb9d2437 | |||
| 83aa176466 | |||
| 0e94e5ecda | |||
| 130485a583 | |||
| f34c10abb5 | |||
| 48b00f0ac1 | |||
| 743329a3af | |||
| f5783f1637 | |||
| 67f61a8d39 | |||
| f7df663dea | |||
| c99278aa58 | |||
| 1765e1b7c2 | |||
| bf1a434d5c | |||
| 9256b5b552 | |||
| 577e4afb3c | |||
| 2a05c04db7 | |||
| a6ffd6b3b2 | |||
| 24eba7c4c1 | |||
| 80de844922 | |||
| a2223c0884 | |||
| 5ffa2b757c | |||
| b660fa27d3 | |||
| 77f0e5e1ba | |||
| 1080822ffa | |||
| 3fef45683c | |||
| cfcc5c5c0b | |||
| 856f1808de | |||
| 4341344545 | |||
| 20392e8840 | |||
| 426fefff81 | |||
| 13013053f7 | |||
| 62b9a4af75 | |||
| 76caf2c812 | |||
| 3d5fce1b9f | |||
| bfe8adbee4 | |||
| 827642303c | |||
| 6b6a0e1257 | |||
| 7a98176a02 | |||
| a93a986ef2 | |||
| 39dbc5ea87 | |||
| cf4d13bee3 | |||
| 0bacde8e0a | |||
| 949cd45bb7 | |||
| 2e9e216641 | |||
| 1ab8ffaceb | |||
| 3cc1726856 | |||
| 30eaa2c3cc | |||
| ba5993195a | |||
| bf42351ebf | |||
| ee277f4d92 | |||
| 00acc7957f | |||
| a931335f24 | |||
| 1ef320a9ec | |||
| 411b7f12b5 | |||
| 611fcfb1c7 | |||
| 6257a51f4f | |||
| e24630bd18 | |||
| 6b0b3a4db7 | |||
| fd19c7c2ab | |||
| 4aa2206699 | |||
| eae23ebf69 | |||
| ecd27f6c3c | |||
| 01f3c72338 | |||
| 87be414c05 | |||
| f6d676cc8a | |||
| 4961241f26 | |||
| 60c944bb94 | |||
| 740c10282f | |||
| 3a4c69f370 | |||
| c3083572fb | |||
| 8ecb00be66 | |||
| 48e707aceb | |||
| e2f9ff2304 | |||
| fa3a72c8f6 | |||
| fc45d90834 | |||
| fcd95cd5c6 | |||
| b8c1ac41d2 | |||
| 90e1ce0906 | |||
| d121fd5b7d | |||
| 4d88fcc1db | |||
| 85fcda178e | |||
| ecc678454b | |||
| 5a85bc691e | |||
| d506a5eea8 | |||
| aefa79413b | |||
| 73e4eb7552 | |||
| dff340530a | |||
| f6ea3e1684 | |||
| f790441505 | |||
| 0c307f7563 | |||
| f89dc9644c | |||
| 735455b523 | |||
| d037cfaf44 | |||
| 293d63425a | |||
| 38f9bb87bc | |||
| 64abadb370 | |||
| 6f85827fcb | |||
| b0e321cfb8 | |||
| 46d0569365 | |||
| 2eea911a0f | |||
| ee4a817121 | |||
| 3d1f914271 | |||
| 7bb0639a75 | |||
| f8f38aab63 | |||
| 75c2bd53aa | |||
| 83921750ae | |||
| 413512eba7 | |||
| e824764dc3 | |||
| 61b12abdab | |||
| 07bd5c7b05 | |||
| 1dc20eda28 | |||
| 5a9299f626 | |||
| 9c86c67f06 | |||
| e6ca7668be | |||
| 0b540b9ad1 | |||
| 514cdf7398 | |||
| 2ab52d73ab | |||
| b3ae172c1e | |||
| a6d1df66ec | |||
| ba92ce342e | |||
| 9f4c715516 | |||
| 5aa47b6e45 | |||
| 3b40d95581 | |||
| 3ad2d91e1c | |||
| d4c586e882 | |||
| 612c547ed3 | |||
| 1a777ce7f3 | |||
| 7ec4f6e297 | |||
| afaa0f3afd | |||
| 8841a002ed | |||
| 6da606aaad | |||
| 51bd155670 | |||
| 8fa16ec1cc | |||
| 04e5a0006d | |||
| a1d2169992 | |||
| 778976f8da | |||
| f81dea58a2 | |||
| e82606a538 | |||
| fe5b28f5b8 | |||
| 82fd0d7eef | |||
| 16761fcb49 | |||
| 4fac5680fb | |||
| 4ec4280e51 | |||
| 15bb77472d | |||
| 5c92d5e081 | |||
| 1626c5f1e7 | |||
| 3b5f0ed05e | |||
| d2298f1c8f | |||
| 085062ab89 | |||
| 9741082467 | |||
| 3db4a05493 | |||
| e3b9df2cec | |||
| 4a4e445a35 | |||
| db0f9b60ac | |||
| d51de390ba | |||
| c14e167a11 | |||
| 2837a85461 | |||
| 282510e113 | |||
| accabe3eee | |||
| 9dbdbaca43 | |||
| 5935bc95b7 | |||
| 4c677e4dcd | |||
| d4c25c9ec0 | |||
| b69df2bc4d | |||
| 7f9363d471 | |||
| 01d86eab66 | |||
| 09e85aa809 | |||
| d49816d2e6 | |||
| 59a00d6768 | |||
| 6bd6c6acba | |||
| be2ff60787 | |||
| 070b9a87b6 | |||
| ecbe6a421e | |||
| 317e68a58c | |||
| 9b42377347 | |||
| 7372a845fb | |||
| cf8c3be030 | |||
| 4eb715cf81 | |||
| d4899fdf1f | |||
| 4142c4d79e | |||
| ca442f8641 | |||
| 3c1491423a | |||
| eb4993d3fb | |||
| aa057da1ca | |||
| 1de09d59fb | |||
| 130a6fe0cf | |||
| e1f7c027d7 | |||
| 396ef5ebe5 | |||
| 840a20db3b | |||
| 8c6f7d1ae9 | |||
| c69fa6221b | |||
| 3c92c81705 | |||
| 297de981c4 | |||
| 53beb054b6 | |||
| 0431492284 | |||
| aed9cc1874 | |||
| c15804d124 | |||
| 1bd208d937 | |||
| b70bcd6bfe | |||
| 74a1d45238 | |||
| 3ada35460d | |||
| 1f133c3d64 | |||
| 4440ce874e | |||
| db302df82a | |||
| b550b58e8f | |||
| ed889b951b | |||
| b603479fe2 | |||
| 7c39b2cea3 | |||
| b1bce7a62b | |||
| fa73e17fba | |||
| f647fc3fe2 | |||
| 6bae80c331 | |||
| ed8255993f | |||
| e1431f31c1 | |||
| 88203fbf4d | |||
| 32a4f805b8 | |||
| 54a86a2a7e | |||
| 06351844bb |
@@ -459,6 +459,7 @@ reference:
|
||||
- mv _build/docs/reference/gdk/gdk4-wayland/ _reference/gdk4-wayland/
|
||||
- mv _build/docs/reference/gsk/gsk4/ _reference/gsk4/
|
||||
- mv _build/docs/reference/gtk/gtk4/ _reference/gtk4/
|
||||
- mv _build/docs/reference/gtk/*.html _reference/gtk4/
|
||||
- mv _build/subprojects/pango/docs/Pango/ _reference/Pango/
|
||||
- mv _build/subprojects/pango/docs/PangoCairo/ _reference/PangoCairo/
|
||||
- mv _build/subprojects/pango/docs/PangoFc/ _reference/PangoFc/
|
||||
|
||||
@@ -1,12 +1,54 @@
|
||||
Overview of Changes in 4.15.1, xx-xx-xxxx
|
||||
Overview of Changes in 4.15.2, xx-xx-xxxx
|
||||
=========================================
|
||||
|
||||
* GtkFileChooserWidget:
|
||||
- Plug some memory leaks
|
||||
- Make Ctrl-Shift-N create a new folder
|
||||
|
||||
* CSS:
|
||||
- Support color(), oklab(), etc (https://www.w3.org/TR/css-color-4/)
|
||||
- Support color-mix() (https://www.w3.org/TR/css-color-5/)
|
||||
- Support relative colors (https://www.w3.org/TR/css-color-5/)
|
||||
|
||||
* Accessibility:
|
||||
- Avoid markup when reading labels
|
||||
|
||||
* GSK:
|
||||
- Subset fonts when serializing node trees
|
||||
|
||||
* Wayland:
|
||||
- Use xdg-dialog protocol for attached dialogs
|
||||
|
||||
* Windows:
|
||||
- Build with UNICODE
|
||||
|
||||
* Debugging:
|
||||
- Add GTK_DEBUG=css for warning about deprecated css syntax
|
||||
|
||||
* Tools:
|
||||
- nodeparser: Add an extract command for data urls
|
||||
|
||||
* Deprecations:
|
||||
- CSS Color functions shade(), lighter(), darker(), alpha(), mix()
|
||||
|
||||
* Translation updates:
|
||||
Hebrew
|
||||
|
||||
|
||||
Overview of Changes in 4.15.1, 21-05-2024
|
||||
=========================================
|
||||
|
||||
* GtkGraphicsOffload:
|
||||
- Don't crash without a child
|
||||
|
||||
* GtkSpinner:
|
||||
- Don't animate when unmapped
|
||||
|
||||
* CSS:
|
||||
- Support the :root selector
|
||||
- Support variables and custom properties
|
||||
- Support variables and custom properties (https://www.w3.org/TR/css-variables-1/)
|
||||
- Implement math functions (https://www.w3.org/TR/css-values-4/)
|
||||
- Support modern syntax and calc in rgb() and hsl()
|
||||
|
||||
* Icontheme:
|
||||
- Make symbolic svg loading more efficient
|
||||
@@ -43,12 +85,20 @@ Overview of Changes in 4.15.1, xx-xx-xxxx
|
||||
|
||||
* Debugging:
|
||||
- Show more texture details in the recorder
|
||||
- Use GTK_DEBUG=css to see CSS deprecations
|
||||
|
||||
* macOS:
|
||||
- Fix problems with events handed back to the OS
|
||||
- Respect GDK_DEBUG=default-settings
|
||||
- Allow applictions to handle Dock > Quit
|
||||
|
||||
* Deprecations:
|
||||
- Use of @name colors in CSS
|
||||
|
||||
* Translation updates:
|
||||
Catalan
|
||||
Georgian
|
||||
Hungarian
|
||||
Korean
|
||||
Portuguese
|
||||
Turkish
|
||||
|
||||
@@ -15,16 +15,16 @@ spec.
|
||||
The following units are supported for basic datatypes:
|
||||
|
||||
Length
|
||||
: px, pt, em, ex, rem, pc, in, cm, mm, calc()
|
||||
: px, pt, em, ex, rem, pc, in, cm, mm
|
||||
|
||||
Percentage
|
||||
: %, calc()
|
||||
: %
|
||||
|
||||
Angle
|
||||
: deg, grad, turn, calc()
|
||||
: deg, rad, grad, turn
|
||||
|
||||
Time
|
||||
: s, ms, calc()
|
||||
: s, ms
|
||||
|
||||
Length values with the em or ex units are resolved using the font
|
||||
size value, unless they occur in setting the font-size itself, in
|
||||
@@ -33,11 +33,15 @@ which case they are resolved using the inherited font size value.
|
||||
The rem unit is resolved using the initial font size value, which is
|
||||
not quite the same as the CSS definition of rem.
|
||||
|
||||
The calc() notation adds considerable expressive power. There are limits
|
||||
on what types can be combined in such an expression (e.g. it does not make
|
||||
sense to add a number and a time). For the full details, see the
|
||||
[CSS3 Values and Units](https://www.w3.org/TR/css3-values/#calc-notation)
|
||||
spec.
|
||||
Length values using physical units (pt, pc, in, cm, mm) are translated
|
||||
to px using the dpi value specified by the -gtk-dpi property, which is
|
||||
different from the CSS definition, which uses a fixed dpi of 96.
|
||||
|
||||
The calc() notation adds considerable expressive power to all of these
|
||||
datatypes. There are limits on what types can be combined in such an
|
||||
expression (e.g. it does not make sense to add a number and a time).
|
||||
For the full details, see the
|
||||
[CSS Values and Units](https://www.w3.org/TR/css-values-4/) spec.
|
||||
|
||||
A common pattern among shorthand properties (called 'four sides') is one
|
||||
where one to four values can be specified, to determine a value for each
|
||||
@@ -82,36 +86,54 @@ color: var(--prop, green);
|
||||
|
||||
## Colors
|
||||
|
||||
GTK extends the CSS syntax with several additional ways to specify colors.
|
||||
### CSS Colors
|
||||
|
||||
Colors can be expressed in numerous ways in CSS (see the
|
||||
[Color Module](https://www.w3.org/TR/css-color-5/). GTK supports
|
||||
many (but not all) of these.
|
||||
|
||||
You can use rgb(), rgba(), hsl() with both the legacy or the modern CSS
|
||||
syntax, and calc() can be used as well in color expressions. hwb(), oklab(),
|
||||
oklch(), color(), color-mix() and relative colors are supported as well.
|
||||
|
||||
### Non-CSS Colors
|
||||
|
||||
GTK extends the CSS syntax with several additional ways to specify colors.
|
||||
|
||||
These extensions are deprecated and should be replaced by the equivalent
|
||||
standard CSS notions.
|
||||
|
||||
The first is a reference to a color defined via a @define-color rule in CSS.
|
||||
The syntax for @define-color rules is as follows:
|
||||
|
||||
```
|
||||
@define-color Name Color
|
||||
@define-color name color
|
||||
```
|
||||
|
||||
To refer to the color defined by a @define-color rule, prefix the name with @.
|
||||
|
||||
The standard CSS mechanisms that should be used instead of @define-color are
|
||||
custom properties, :root and var().
|
||||
|
||||
GTK also supports color expressions, which allow colors to be transformed to
|
||||
new ones. Color expressions can be nested, providing a rich language to
|
||||
define colors. Color expressions resemble functions, taking 1 or more colors
|
||||
and in some cases a number as arguments.
|
||||
|
||||
`lighter(Color)`
|
||||
: produces a brighter variant of Color
|
||||
`lighter(color)`
|
||||
: produces a brighter variant of `color`.
|
||||
|
||||
`darker(Color)`
|
||||
: produces a darker variant of Color
|
||||
`darker(color)`
|
||||
: produces a darker variant of `color`.
|
||||
|
||||
`shade(Color, Number)`
|
||||
: changes the lightness of Color. The number ranges from 0 for black to 2 for white.
|
||||
`shade(color, number)`
|
||||
: changes the lightness of `color`. The `number` ranges from 0 for black to 2 for white.
|
||||
|
||||
`alpha(Color, Number)`
|
||||
: replaces the alpha value of color with number (between 0 and 1)
|
||||
`alpha(color, number)`
|
||||
: multiplies the alpha value of `color` by `number` (between 0 and 1).
|
||||
|
||||
`mix(Color1, Color2, Number)`
|
||||
: interpolates between the two colors
|
||||
`mix(color1, color2, number)`
|
||||
: interpolates between the two colors.
|
||||
|
||||
## Images
|
||||
|
||||
@@ -119,7 +141,7 @@ GTK extends the CSS syntax for images and also uses it for specifying icons.
|
||||
To load a themed icon, use
|
||||
|
||||
```
|
||||
-gtk-icontheme(Name)
|
||||
-gtk-icontheme(name)
|
||||
```
|
||||
|
||||
The specified icon name is used to look up a themed icon, while taking into
|
||||
@@ -148,14 +170,14 @@ and the
|
||||
syntax makes this available. -gtk-recolor requires a url as first argument.
|
||||
The remaining arguments specify the color palette to use. If the palette is
|
||||
not explicitly specified, the current value of the -gtk-icon-palette property
|
||||
is used.
|
||||
is used.
|
||||
|
||||
GTK supports scaled rendering on hi-resolution displays. This works best if
|
||||
images can specify normal and hi-resolution variants. From CSS, this can be
|
||||
done with
|
||||
|
||||
```
|
||||
-gtk-scaled(Image1, Image2)
|
||||
-gtk-scaled(image1, image2)
|
||||
```
|
||||
|
||||
## GTK CSS Properties
|
||||
|
||||
@@ -18,6 +18,7 @@ SYNOPSIS
|
||||
|
|
||||
| **gtk4-rendernode-tool** benchmark [OPTIONS...] <FILE>
|
||||
| **gtk4-rendernode-tool** compare [OPTIONS...] <FILE1> <FILE2>
|
||||
| **gtk4-rendernode-tool** extract [OPTIONS...] <FILE>
|
||||
| **gtk4-rendernode-tool** info [OPTIONS...] <FILE>
|
||||
| **gtk4-rendernode-tool** render [OPTIONS...] <FILE> [<FILE>]
|
||||
| **gtk4-rendernode-tool** show [OPTIONS...] <FILE>
|
||||
@@ -99,3 +100,15 @@ exit code is 1. If the images are identical, it is 0.
|
||||
``--quiet``
|
||||
|
||||
Don't write results to stdout.
|
||||
|
||||
|
||||
Extract
|
||||
^^^^^^^
|
||||
|
||||
The ``extract`` command saves all the data urls found in a node file to a given
|
||||
directory. The file names for the extracted files are derived from the mimetype
|
||||
of the url.
|
||||
|
||||
``--dir=DIRECTORY``
|
||||
|
||||
Save extracted files in ``DIRECTORY`` (defaults to the current directory).
|
||||
|
||||
@@ -77,11 +77,13 @@ content_files = [
|
||||
"section-tree-widget.md",
|
||||
"migrating-2to4.md",
|
||||
"migrating-3to4.md",
|
||||
"migrating-4to5.md",
|
||||
"broadway.md",
|
||||
"osx.md",
|
||||
"wayland.md",
|
||||
"windows.md",
|
||||
"x11.md",
|
||||
"tools.md",
|
||||
"visual_index.md",
|
||||
]
|
||||
content_images = [
|
||||
|
||||
@@ -14,6 +14,7 @@ expand_content_md_files = [
|
||||
'running.md',
|
||||
'migrating-2to4.md',
|
||||
'migrating-3to4.md',
|
||||
'migrating-4to5.md',
|
||||
'actions.md',
|
||||
'input-handling.md',
|
||||
'drawing-model.md',
|
||||
@@ -25,7 +26,8 @@ expand_content_md_files = [
|
||||
'section-tree-widget.md',
|
||||
'section-list-widget.md',
|
||||
'question_index.md',
|
||||
'visual_index.md'
|
||||
'visual_index.md',
|
||||
'tools.md',
|
||||
]
|
||||
|
||||
gtk_images = []
|
||||
@@ -60,39 +62,39 @@ if get_option('documentation')
|
||||
build_by_default: true,
|
||||
install: true,
|
||||
install_dir: docs_dir,
|
||||
install_tag: 'doc',
|
||||
)
|
||||
endif
|
||||
|
||||
rst2man = find_program('rst2man', 'rst2man.py', required: false)
|
||||
if get_option('man-pages') and not rst2man.found()
|
||||
error('No rst2man found, but man pages were explicitly enabled')
|
||||
rst2man = find_program('rst2man', 'rst2man.py', required: get_option('man-pages'))
|
||||
rst2html5 = find_program('rst2html5', 'rst2html5.py', required: get_option('documentation'))
|
||||
|
||||
rst_files = [
|
||||
[ 'gtk4-broadwayd', '1' ],
|
||||
[ 'gtk4-builder-tool', '1' ],
|
||||
[ 'gtk4-encode-symbolic-svg', '1', ],
|
||||
[ 'gtk4-launch', '1', ],
|
||||
[ 'gtk4-query-settings', '1', ],
|
||||
[ 'gtk4-rendernode-tool', '1' ],
|
||||
[ 'gtk4-update-icon-cache', '1', ],
|
||||
[ 'gtk4-path-tool', '1', ],
|
||||
]
|
||||
|
||||
if get_option('build-demos')
|
||||
rst_files += [
|
||||
[ 'gtk4-demo', '1', ],
|
||||
[ 'gtk4-demo-application', '1', ],
|
||||
[ 'gtk4-widget-factory', '1', ],
|
||||
[ 'gtk4-icon-browser', '1', ],
|
||||
[ 'gtk4-node-editor', '1', ],
|
||||
]
|
||||
endif
|
||||
|
||||
if get_option('man-pages') and rst2man.found()
|
||||
rst_files = [
|
||||
[ 'gtk4-broadwayd', '1' ],
|
||||
[ 'gtk4-builder-tool', '1' ],
|
||||
[ 'gtk4-encode-symbolic-svg', '1', ],
|
||||
[ 'gtk4-launch', '1', ],
|
||||
[ 'gtk4-query-settings', '1', ],
|
||||
[ 'gtk4-rendernode-tool', '1' ],
|
||||
[ 'gtk4-update-icon-cache', '1', ],
|
||||
[ 'gtk4-path-tool', '1', ],
|
||||
]
|
||||
rst2x_flags = [
|
||||
'--syntax-highlight=none',
|
||||
]
|
||||
|
||||
if get_option('build-demos')
|
||||
rst_files += [
|
||||
[ 'gtk4-demo', '1', ],
|
||||
[ 'gtk4-demo-application', '1', ],
|
||||
[ 'gtk4-widget-factory', '1', ],
|
||||
[ 'gtk4-icon-browser', '1', ],
|
||||
[ 'gtk4-node-editor', '1', ],
|
||||
]
|
||||
endif
|
||||
|
||||
rst2man_flags = [
|
||||
'--syntax-highlight=none',
|
||||
]
|
||||
if get_option('man-pages')
|
||||
|
||||
foreach rst: rst_files
|
||||
man_name = rst[0]
|
||||
@@ -103,12 +105,34 @@ if get_option('man-pages') and rst2man.found()
|
||||
output: '@0@.@1@'.format(man_name, man_section),
|
||||
command: [
|
||||
rst2man,
|
||||
rst2man_flags,
|
||||
rst2x_flags,
|
||||
'@INPUT@',
|
||||
],
|
||||
capture: true,
|
||||
install: true,
|
||||
install_dir: get_option('mandir') / 'man@0@'.format(man_section),
|
||||
install_tag: 'doc',
|
||||
)
|
||||
endforeach
|
||||
endif
|
||||
|
||||
if get_option('documentation')
|
||||
|
||||
foreach rst: rst_files
|
||||
man_name = rst[0]
|
||||
|
||||
custom_target(
|
||||
input: '@0@.rst'.format(man_name),
|
||||
output: '@0@.html'.format(man_name),
|
||||
command: [
|
||||
rst2html5,
|
||||
rst2x_flags,
|
||||
'@INPUT@',
|
||||
],
|
||||
capture: true,
|
||||
install: true,
|
||||
install_dir: docs_dir / 'gtk4',
|
||||
install_tag: 'doc',
|
||||
)
|
||||
endforeach
|
||||
endif
|
||||
|
||||
@@ -58,7 +58,7 @@ use a GtkLabel.
|
||||
If you have a need for custom drawing that fits into the current
|
||||
(dark or light) theme, e.g. for rendering a graph, you can still
|
||||
get the current style foreground color, using
|
||||
[method@Gtk.Widget.get_style_color].
|
||||
[method@Gtk.Widget.get_color].
|
||||
|
||||
## Local stylesheets are going away
|
||||
|
||||
@@ -73,6 +73,103 @@ GTK 5 will no longer provide this functionality. The recommendations
|
||||
is to use a global stylesheet (i.e. gtk_style_context_add_provider_for_display())
|
||||
and rely on style classes to make your CSS apply only where desired.
|
||||
|
||||
## Non-standard CSS extensions are going away
|
||||
|
||||
GTK's CSS machinery has a some non-standard extensions around colors:
|
||||
named colors with \@define-color and color functions: lighter(), darker(),
|
||||
shade(), alpha(), mix().
|
||||
|
||||
GTK now implements equivalent functionality from the CSS specs.
|
||||
|
||||
### \@define-color is going away
|
||||
|
||||
\@define-color should be replaced by custom properties in the :root scope.
|
||||
|
||||
Instead of
|
||||
|
||||
```
|
||||
@define-color fg_color #2e3436
|
||||
|
||||
...
|
||||
|
||||
box {
|
||||
color: @fg_color;
|
||||
}
|
||||
```
|
||||
|
||||
use
|
||||
|
||||
```
|
||||
:root {
|
||||
--fg-color: #2e3436;
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
box {
|
||||
color: var(--fg-color);
|
||||
}
|
||||
```
|
||||
|
||||
For more information about custom CSS properties and variables, see the
|
||||
[CSS Custom Properties for Cascading Variables](https://www.w3.org/TR/css-variables-1/)
|
||||
spec.
|
||||
|
||||
### Color expressions are going away
|
||||
|
||||
The color functions can all be replaced by combinations of calc() and color-mix().
|
||||
|
||||
ligher(c) and darker(c) are just shade(c, 1.3) or shade(c, 0.7), respectively, and
|
||||
thus can be handled the same way as shade in the examples below.
|
||||
|
||||
Replace
|
||||
|
||||
```
|
||||
a {
|
||||
color: mix(red, green, 0.8);
|
||||
}
|
||||
|
||||
b {
|
||||
color: alpha(green, 0.6);
|
||||
}
|
||||
|
||||
c {
|
||||
color: shade(red, 1.3);
|
||||
}
|
||||
|
||||
d {
|
||||
color: shade(red, 0.7);
|
||||
}
|
||||
```
|
||||
|
||||
with
|
||||
|
||||
```
|
||||
a {
|
||||
color: color-mix(in srgb, red, green 80%);
|
||||
}
|
||||
|
||||
b {
|
||||
color: rgb(from green, r g b / calc(alpha * 0.6));
|
||||
}
|
||||
|
||||
c {
|
||||
color: hsl(from red, h calc(s * 1.3) calc(l * 1.3));
|
||||
}
|
||||
|
||||
d {
|
||||
color: hsl(from red, h calc(s * 0.7) calc(l * 0.7));
|
||||
}
|
||||
```
|
||||
|
||||
Variations of these replacements are possible.
|
||||
|
||||
Note that GTK has historically computed mix() and shade() values in the SRGB and HSL
|
||||
colorspaces, but using OKLAB instead might yield slightly better results.
|
||||
|
||||
For more information about color-mix(), see the
|
||||
[CSS Color](https://drafts.csswg.org/css-color-5) spec.
|
||||
|
||||
## Chooser interfaces are going away
|
||||
|
||||
The GtkColorChooser, GtkFontChooser, GtkFileChooser and GtkAppChooser
|
||||
|
||||
@@ -64,6 +64,6 @@ GTK is divided into three parts:
|
||||
[cairo]: https://www.cairographics.org/manual/
|
||||
[opengl]: https://www.opengl.org/about/
|
||||
[vulkan]: https://www.vulkan.org/
|
||||
[pango]: https://docs.gtk.org/pango/
|
||||
[pango]: https://docs.gtk.org/Pango/
|
||||
[gdkpixbuf]: https://docs.gtk.org/gdk-pixbuf/
|
||||
[graphene]: https://ebassi.github.io/graphene/
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
Title: Tools and Demos
|
||||
|
||||
GTK ships with a number of tools and demos that come with their own
|
||||
documentation in the form of man pages.
|
||||
|
||||
- [gtk4-broadwayd](gtk4-broadwayd.html)
|
||||
- [gtk4-builder-tool](gtk4-builder-tool.html)
|
||||
- [gtk4-demo](gtk4-demo.html)
|
||||
- [gtk4-demo-application](gtk4-demo-application.html)
|
||||
- [gtk4-encode-symbolic-svg](gtk4-encode-symbolic-svg.html)
|
||||
- [gtk4-icon-browser](gtk4-icon-browser.html)
|
||||
- [gtk4-launch](gtk4-launch.html)
|
||||
- [gtk4-node-editor](gtk4-node-editor.html)
|
||||
- [gtk4-path-tool](gtk4-path-tool.html)
|
||||
- [gtk4-query-settings](gtk4-query-settings.html)
|
||||
- [gtk4-rendernode-tool](gtk4-rendernode-tool.html)
|
||||
- [gtk4-update-icon-cache](gtk4-update-icon-cache.html)
|
||||
- [gtk4-widget-factory](gtk4-widget-factory.html)
|
||||
@@ -522,8 +522,6 @@ gdk_clipboard_get_content (GdkClipboard *clipboard)
|
||||
*
|
||||
* If the clipboard is not local, this function does nothing but report success.
|
||||
*
|
||||
* The @callback must call [method@Gdk.Clipboard.store_finish].
|
||||
*
|
||||
* The purpose of this call is to preserve clipboard contents beyond the
|
||||
* lifetime of an application, so this function is typically called on
|
||||
* exit. Depending on the platform, the functionality may not be available
|
||||
@@ -638,9 +636,6 @@ gdk_clipboard_read_internal (GdkClipboard *clipboard,
|
||||
* Asynchronously requests an input stream to read the @clipboard's
|
||||
* contents from.
|
||||
*
|
||||
* When the operation is finished @callback will be called. You must then
|
||||
* call [method@Gdk.Clipboard.read_finish] to get the result of the operation.
|
||||
*
|
||||
* The clipboard will choose the most suitable mime type from the given list
|
||||
* to fulfill the request, preferring the ones listed first.
|
||||
*/
|
||||
@@ -834,9 +829,6 @@ gdk_clipboard_read_value_internal (GdkClipboard *clipboard,
|
||||
* Asynchronously request the @clipboard contents converted to the given
|
||||
* @type.
|
||||
*
|
||||
* When the operation is finished @callback will be called. You must then call
|
||||
* [method@Gdk.Clipboard.read_value_finish] to get the resulting `GValue`.
|
||||
*
|
||||
* For local clipboard contents that are available in the given `GType`,
|
||||
* the value will be copied directly. Otherwise, GDK will try to use
|
||||
* [func@content_deserialize_async] to convert the clipboard's data.
|
||||
@@ -895,9 +887,6 @@ gdk_clipboard_read_value_finish (GdkClipboard *clipboard,
|
||||
*
|
||||
* Asynchronously request the @clipboard contents converted to a `GdkPixbuf`.
|
||||
*
|
||||
* When the operation is finished @callback will be called. You must then
|
||||
* call [method@Gdk.Clipboard.read_texture_finish] to get the result.
|
||||
*
|
||||
* This is a simple wrapper around [method@Gdk.Clipboard.read_value_async].
|
||||
* Use that function or [method@Gdk.Clipboard.read_async] directly if you
|
||||
* need more control over the operation.
|
||||
@@ -960,9 +949,6 @@ gdk_clipboard_read_texture_finish (GdkClipboard *clipboard,
|
||||
*
|
||||
* Asynchronously request the @clipboard contents converted to a string.
|
||||
*
|
||||
* When the operation is finished @callback will be called. You must then
|
||||
* call [method@Gdk.Clipboard.read_text_finish] to get the result.
|
||||
*
|
||||
* This is a simple wrapper around [method@Gdk.Clipboard.read_value_async].
|
||||
* Use that function or [method@Gdk.Clipboard.read_async] directly if you
|
||||
* need more control over the operation.
|
||||
|
||||
@@ -540,9 +540,6 @@ deserialize_not_found (GdkContentDeserializer *deserializer)
|
||||
*
|
||||
* The default I/O priority is %G_PRIORITY_DEFAULT (i.e. 0), and lower numbers
|
||||
* indicate a higher priority.
|
||||
*
|
||||
* When the operation is finished, @callback will be called. You must then
|
||||
* call [func@Gdk.content_deserialize_finish] to get the result of the operation.
|
||||
*/
|
||||
void
|
||||
gdk_content_deserialize_async (GInputStream *stream,
|
||||
|
||||
@@ -279,10 +279,6 @@ gdk_content_provider_content_changed (GdkContentProvider *provider)
|
||||
* Asynchronously writes the contents of @provider to @stream in the given
|
||||
* @mime_type.
|
||||
*
|
||||
* When the operation is finished @callback will be called. You must then call
|
||||
* [method@Gdk.ContentProvider.write_mime_type_finish] to get the result
|
||||
* of the operation.
|
||||
*
|
||||
* The given mime type does not need to be listed in the formats returned by
|
||||
* [method@Gdk.ContentProvider.ref_formats]. However, if the given `GType` is
|
||||
* not supported, `G_IO_ERROR_NOT_SUPPORTED` will be reported.
|
||||
|
||||
@@ -546,9 +546,6 @@ serialize_not_found (GdkContentSerializer *serializer)
|
||||
*
|
||||
* The default I/O priority is %G_PRIORITY_DEFAULT (i.e. 0), and lower numbers
|
||||
* indicate a higher priority.
|
||||
*
|
||||
* When the operation is finished, @callback will be called. You must then
|
||||
* call [func@Gdk.content_serialize_finish] to get the result of the operation.
|
||||
*/
|
||||
void
|
||||
gdk_content_serialize_async (GOutputStream *stream,
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ GdkCursor* gdk_cursor_new_from_name (const char *name,
|
||||
GdkCursor *fallback);
|
||||
|
||||
/**
|
||||
* GdkCursorGetTestureCallback:
|
||||
* GdkCursorGetTextureCallback:
|
||||
* @cursor: the `GdkCursor`
|
||||
* @cursor_size: the nominal cursor size, in application pixels
|
||||
* @scale: the device scale
|
||||
|
||||
@@ -62,6 +62,13 @@ struct _GdkDmabufTextureClass
|
||||
GdkTextureClass parent_class;
|
||||
};
|
||||
|
||||
/**
|
||||
* gdk_dmabuf_error_quark:
|
||||
*
|
||||
* Registers an error quark for [class@Gdk.DmabufTexture] errors.
|
||||
*
|
||||
* Returns: the error quark
|
||||
**/
|
||||
G_DEFINE_QUARK (gdk-dmabuf-error-quark, gdk_dmabuf_error)
|
||||
|
||||
G_DEFINE_TYPE (GdkDmabufTexture, gdk_dmabuf_texture, GDK_TYPE_TEXTURE)
|
||||
|
||||
+2
-6
@@ -134,7 +134,7 @@ gdk_drop_read_local_async (GdkDrop *self,
|
||||
|
||||
g_object_get (priv->drag, "content", &content, NULL);
|
||||
content_formats = gdk_content_provider_ref_formats (content);
|
||||
g_object_unref (content);
|
||||
g_object_unref (content);
|
||||
content_formats = gdk_content_formats_union_serialize_mime_types (content_formats);
|
||||
mime_type = gdk_content_formats_match_mime_type (content_formats, formats);
|
||||
|
||||
@@ -784,7 +784,7 @@ gdk_drop_read_value_internal (GdkDrop *self,
|
||||
GdkContentFormats *formats;
|
||||
GValue *value;
|
||||
GTask *task;
|
||||
|
||||
|
||||
g_return_if_fail (priv->state != GDK_DROP_STATE_FINISHED);
|
||||
|
||||
task = g_task_new (self, cancellable, callback, user_data);
|
||||
@@ -849,10 +849,6 @@ gdk_drop_read_value_internal (GdkDrop *self,
|
||||
* Asynchronously request the drag operation's contents converted
|
||||
* to the given @type.
|
||||
*
|
||||
* When the operation is finished @callback will be called. You must
|
||||
* then call [method@Gdk.Drop.read_value_finish] to get the resulting
|
||||
* `GValue`.
|
||||
*
|
||||
* For local drag-and-drop operations that are available in the given
|
||||
* `GType`, the value will be copied directly. Otherwise, GDK will
|
||||
* try to use [func@Gdk.content_deserialize_async] to convert the data.
|
||||
|
||||
@@ -1371,6 +1371,8 @@ gdk_event_get_modifier_state (GdkEvent *event)
|
||||
* Extract the event surface relative x/y coordinates from an event.
|
||||
*
|
||||
* This position is in [surface coordinates](coordinates.html).
|
||||
*
|
||||
* Returns: whether the positions were set
|
||||
*/
|
||||
gboolean
|
||||
gdk_event_get_position (GdkEvent *event,
|
||||
|
||||
@@ -152,6 +152,13 @@ enum {
|
||||
|
||||
static GParamSpec *properties[LAST_PROP] = { NULL, };
|
||||
|
||||
/**
|
||||
* gdk_gl_error_quark:
|
||||
*
|
||||
* Registers an error quark for [class@Gdk.GLContext] errors.
|
||||
*
|
||||
* Returns: the error quark
|
||||
**/
|
||||
G_DEFINE_QUARK (gdk-gl-error-quark, gdk_gl_error)
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdkGLContext, gdk_gl_context, GDK_TYPE_DRAW_CONTEXT)
|
||||
|
||||
+13
-2
@@ -396,10 +396,18 @@ gboolean
|
||||
*/
|
||||
char *
|
||||
gdk_rgba_to_string (const GdkRGBA *rgba)
|
||||
{
|
||||
return g_string_free (gdk_rgba_print (rgba, g_string_new ("")), FALSE);
|
||||
}
|
||||
|
||||
GString *
|
||||
gdk_rgba_print (const GdkRGBA *rgba,
|
||||
GString *string)
|
||||
{
|
||||
if (rgba->alpha > 0.999)
|
||||
{
|
||||
return g_strdup_printf ("rgb(%d,%d,%d)",
|
||||
g_string_append_printf (string,
|
||||
"rgb(%d,%d,%d)",
|
||||
(int)(0.5 + CLAMP (rgba->red, 0., 1.) * 255.),
|
||||
(int)(0.5 + CLAMP (rgba->green, 0., 1.) * 255.),
|
||||
(int)(0.5 + CLAMP (rgba->blue, 0., 1.) * 255.));
|
||||
@@ -410,12 +418,15 @@ gdk_rgba_to_string (const GdkRGBA *rgba)
|
||||
|
||||
g_ascii_formatd (alpha, G_ASCII_DTOSTR_BUF_SIZE, "%g", CLAMP (rgba->alpha, 0, 1));
|
||||
|
||||
return g_strdup_printf ("rgba(%d,%d,%d,%s)",
|
||||
g_string_append_printf (string,
|
||||
"rgba(%d,%d,%d,%s)",
|
||||
(int)(0.5 + CLAMP (rgba->red, 0., 1.) * 255.),
|
||||
(int)(0.5 + CLAMP (rgba->green, 0., 1.) * 255.),
|
||||
(int)(0.5 + CLAMP (rgba->blue, 0., 1.) * 255.),
|
||||
alpha);
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
||||
@@ -72,5 +72,8 @@ _gdk_rgba_equal (gconstpointer p1,
|
||||
rgba1->alpha == rgba2->alpha;
|
||||
}
|
||||
|
||||
GString * gdk_rgba_print (const GdkRGBA *rgba,
|
||||
GString *string);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -50,6 +50,13 @@
|
||||
#include "loaders/gdktiffprivate.h"
|
||||
#include "loaders/gdkjpegprivate.h"
|
||||
|
||||
/**
|
||||
* gdk_texture_error_quark:
|
||||
*
|
||||
* Registers an error quark for [class@Gdk.Texture] errors.
|
||||
*
|
||||
* Returns: the error quark
|
||||
**/
|
||||
G_DEFINE_QUARK (gdk-texture-error-quark, gdk_texture_error)
|
||||
|
||||
/* HACK: So we don't need to include any (not-yet-created) GSK or GTK headers */
|
||||
|
||||
@@ -767,9 +767,6 @@ gdk_toplevel_titlebar_gesture (GdkToplevel *toplevel,
|
||||
* This function asynchronously obtains a handle for a toplevel surface
|
||||
* that can be passed to other processes.
|
||||
*
|
||||
* When a handle has been obtained, @callback will be called, and can
|
||||
* receive the handle via [method@Gdk.Toplevel.export_handle_finish].
|
||||
*
|
||||
* It is an error to call this function on a surface that is already
|
||||
* exported.
|
||||
*
|
||||
|
||||
+6
-3
@@ -118,9 +118,12 @@ typedef enum
|
||||
|
||||
/**
|
||||
* GdkTitlebarGesture:
|
||||
* @GDK_TITLEBAR_GESTURE_DOUBLE_CLICK:
|
||||
* @GDK_TITLEBAR_GESTURE_RIGHT_CLICK:
|
||||
* @GDK_TITLEBAR_GESTURE_MIDDLE_CLICK:
|
||||
* @GDK_TITLEBAR_GESTURE_DOUBLE_CLICK: double click gesture
|
||||
* @GDK_TITLEBAR_GESTURE_RIGHT_CLICK: right click gesture
|
||||
* @GDK_TITLEBAR_GESTURE_MIDDLE_CLICK: middle click gesture
|
||||
*
|
||||
* The kind of title bar gesture to emit with
|
||||
* [method@Gdk.Toplevel.titlebar_gesture].
|
||||
*
|
||||
* Since: 4.4
|
||||
*/
|
||||
|
||||
+17
-6
@@ -94,6 +94,13 @@ enum {
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
/**
|
||||
* gdk_vulkan_error_quark:
|
||||
*
|
||||
* Registers an error quark for [class@Gdk.VulkanContext] errors.
|
||||
*
|
||||
* Returns: the error quark
|
||||
**/
|
||||
G_DEFINE_QUARK (gdk-vulkan-error-quark, gdk_vulkan_error)
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
@@ -1859,8 +1866,9 @@ gdk_display_unref_vulkan (GdkDisplay *display)
|
||||
{
|
||||
g_free (key);
|
||||
vkDestroyShaderModule (display->vk_device,
|
||||
value,
|
||||
*((VkShaderModule *)value),
|
||||
NULL);
|
||||
g_free (value);
|
||||
}
|
||||
g_hash_table_unref (display->vk_shader_modules);
|
||||
|
||||
@@ -1988,13 +1996,13 @@ VkShaderModule
|
||||
gdk_display_get_vk_shader_module (GdkDisplay *self,
|
||||
const char *resource_name)
|
||||
{
|
||||
VkShaderModule shader;
|
||||
VkShaderModule *shader;
|
||||
GError *error = NULL;
|
||||
GBytes *bytes;
|
||||
|
||||
shader = g_hash_table_lookup (self->vk_shader_modules, resource_name);
|
||||
if (shader)
|
||||
return shader;
|
||||
return *shader;
|
||||
|
||||
bytes = g_resources_lookup_data (resource_name, 0, &error);
|
||||
if (bytes == NULL)
|
||||
@@ -2004,6 +2012,7 @@ gdk_display_get_vk_shader_module (GdkDisplay *self,
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
shader = g_new0 (VkShaderModule, 1);
|
||||
if (GDK_VK_CHECK (vkCreateShaderModule, self->vk_device,
|
||||
&(VkShaderModuleCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
|
||||
@@ -2011,18 +2020,20 @@ gdk_display_get_vk_shader_module (GdkDisplay *self,
|
||||
.pCode = (uint32_t *) g_bytes_get_data (bytes, NULL),
|
||||
},
|
||||
NULL,
|
||||
&shader) == VK_SUCCESS)
|
||||
shader) == VK_SUCCESS)
|
||||
{
|
||||
g_hash_table_insert (self->vk_shader_modules, g_strdup (resource_name), shader);
|
||||
}
|
||||
else
|
||||
{
|
||||
shader = VK_NULL_HANDLE;
|
||||
g_free (shader);
|
||||
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
return shader;
|
||||
return *shader;
|
||||
}
|
||||
|
||||
#else /* GDK_RENDERING_VULKAN */
|
||||
|
||||
@@ -96,12 +96,12 @@ _gdk_macos_drag_surface_constructed (GObject *object)
|
||||
defer:NO
|
||||
screen:screen];
|
||||
|
||||
_gdk_macos_surface_set_native (self, window);
|
||||
|
||||
[window setOpaque:NO];
|
||||
[window setBackgroundColor:[NSColor clearColor]];
|
||||
[window setDecorated:NO];
|
||||
|
||||
_gdk_macos_surface_set_native (self, window);
|
||||
|
||||
frame_clock = _gdk_frame_clock_idle_new ();
|
||||
gdk_surface_set_frame_clock (surface, frame_clock);
|
||||
g_object_unref (frame_clock);
|
||||
|
||||
@@ -52,6 +52,7 @@ gdk_macos_popup_surface_layout (GdkMacosPopupSurface *self,
|
||||
GdkRectangle bounds;
|
||||
GdkRectangle final_rect;
|
||||
int x, y;
|
||||
int shadow_left, shadow_right, shadow_top, shadow_bottom;
|
||||
|
||||
g_assert (GDK_IS_MACOS_POPUP_SURFACE (self));
|
||||
g_assert (layout != NULL);
|
||||
@@ -68,10 +69,19 @@ gdk_macos_popup_surface_layout (GdkMacosPopupSurface *self,
|
||||
monitor = _gdk_macos_surface_get_best_monitor (GDK_MACOS_SURFACE (self));
|
||||
gdk_macos_monitor_get_workarea (monitor, &bounds);
|
||||
|
||||
gdk_popup_layout_get_shadow_width (layout,
|
||||
&shadow_left,
|
||||
&shadow_right,
|
||||
&shadow_top,
|
||||
&shadow_bottom);
|
||||
|
||||
gdk_surface_layout_popup_helper (GDK_SURFACE (self),
|
||||
width,
|
||||
height,
|
||||
0, 0, 0, 0, /* shadow-left/right/top/bottom */
|
||||
shadow_left,
|
||||
shadow_right,
|
||||
shadow_top,
|
||||
shadow_bottom,
|
||||
monitor,
|
||||
&bounds,
|
||||
self->layout,
|
||||
@@ -306,14 +316,14 @@ _gdk_macos_popup_surface_constructed (GObject *object)
|
||||
defer:NO
|
||||
screen:screen];
|
||||
|
||||
_gdk_macos_surface_set_native (GDK_MACOS_SURFACE (self), window);
|
||||
|
||||
[window setOpaque:NO];
|
||||
[window setBackgroundColor:[NSColor clearColor]];
|
||||
[window setDecorated:NO];
|
||||
[window setExcludedFromWindowsMenu:YES];
|
||||
[window setLevel:NSPopUpMenuWindowLevel];
|
||||
|
||||
_gdk_macos_surface_set_native (GDK_MACOS_SURFACE (self), window);
|
||||
|
||||
gdk_surface_set_frame_clock (surface, gdk_surface_get_frame_clock (surface->parent));
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
|
||||
@@ -591,11 +591,11 @@ _gdk_macos_toplevel_surface_constructed (GObject *object)
|
||||
defer:NO
|
||||
screen:screen];
|
||||
|
||||
_gdk_macos_surface_set_native (GDK_MACOS_SURFACE (self), window);
|
||||
|
||||
/* Allow NSWindow to go fullscreen */
|
||||
[window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
|
||||
|
||||
_gdk_macos_surface_set_native (GDK_MACOS_SURFACE (self), window);
|
||||
|
||||
frame_clock = _gdk_frame_clock_idle_new ();
|
||||
gdk_surface_set_frame_clock (surface, frame_clock);
|
||||
g_object_unref (frame_clock);
|
||||
|
||||
+1
-1
@@ -128,8 +128,8 @@ install_headers(gdk_deprecated_headers, subdir: 'gtk-4.0/gdk/deprecated')
|
||||
gdk_sources = gdk_public_sources + gdk_deprecated_sources
|
||||
|
||||
gdk_private_h_sources = files([
|
||||
'gdkeventsprivate.h',
|
||||
'gdkdevicetoolprivate.h',
|
||||
'gdkeventsprivate.h',
|
||||
'gdkhslaprivate.h',
|
||||
'gdkmonitorprivate.h',
|
||||
'gdkseatdefaultprivate.h',
|
||||
|
||||
@@ -97,6 +97,7 @@
|
||||
#define OUTPUT_VERSION_WITH_DONE 2
|
||||
#define NO_XDG_OUTPUT_DONE_SINCE_VERSION 3
|
||||
#define OUTPUT_VERSION 3
|
||||
#define XDG_WM_DIALOG_VERSION 1
|
||||
|
||||
#ifdef HAVE_TOPLEVEL_STATE_SUSPENDED
|
||||
#define XDG_WM_BASE_VERSION 6
|
||||
@@ -382,6 +383,13 @@ gdk_registry_handle_global (void *data,
|
||||
{
|
||||
display_wayland->zxdg_shell_v6_id = id;
|
||||
}
|
||||
else if (strcmp (interface, "xdg_wm_dialog_v1") == 0)
|
||||
{
|
||||
display_wayland->xdg_wm_dialog =
|
||||
wl_registry_bind (display_wayland->wl_registry, id,
|
||||
&xdg_wm_dialog_v1_interface,
|
||||
MIN (version, XDG_WM_DIALOG_VERSION));
|
||||
}
|
||||
else if (strcmp (interface, "gtk_shell1") == 0)
|
||||
{
|
||||
display_wayland->gtk_shell =
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <gdk/wayland/viewporter-client-protocol.h>
|
||||
#include <gdk/wayland/presentation-time-client-protocol.h>
|
||||
#include <gdk/wayland/single-pixel-buffer-v1-client-protocol.h>
|
||||
#include <gdk/wayland/xdg-dialog-v1-client-protocol.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <gdk/gdkkeys.h>
|
||||
@@ -102,6 +103,7 @@ struct _GdkWaylandDisplay
|
||||
DmabufFormatsInfo *dmabuf_formats_info;
|
||||
struct xdg_wm_base *xdg_wm_base;
|
||||
struct zxdg_shell_v6 *zxdg_shell_v6;
|
||||
struct xdg_wm_dialog_v1 *xdg_wm_dialog;
|
||||
struct gtk_shell1 *gtk_shell;
|
||||
struct wl_data_device_manager *data_device_manager;
|
||||
struct wl_subcompositor *subcompositor;
|
||||
|
||||
@@ -3866,9 +3866,25 @@ pointer_surface_leave (void *data,
|
||||
pointer_surface_update_scale (device);
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_surface_preferred_buffer_scale (void *data,
|
||||
struct wl_surface *wl_surface,
|
||||
int32_t factor)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_surface_preferred_buffer_transform (void *data,
|
||||
struct wl_surface *wl_surface,
|
||||
uint32_t transform)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct wl_surface_listener pointer_surface_listener = {
|
||||
pointer_surface_enter,
|
||||
pointer_surface_leave
|
||||
pointer_surface_leave,
|
||||
pointer_surface_preferred_buffer_scale,
|
||||
pointer_surface_preferred_buffer_transform,
|
||||
};
|
||||
|
||||
static void
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <wayland/presentation-time-client-protocol.h>
|
||||
#include <wayland/xdg-shell-unstable-v6-client-protocol.h>
|
||||
#include <wayland/xdg-foreign-unstable-v2-client-protocol.h>
|
||||
#include <wayland/xdg-dialog-v1-client-protocol.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
@@ -84,6 +85,7 @@ struct _GdkWaylandToplevel
|
||||
struct gtk_surface1 *gtk_surface;
|
||||
struct xdg_toplevel *xdg_toplevel;
|
||||
struct zxdg_toplevel_v6 *zxdg_toplevel_v6;
|
||||
struct xdg_dialog_v1 *xdg_dialog;
|
||||
} display_server;
|
||||
|
||||
GdkWaylandToplevel *transient_for;
|
||||
@@ -205,6 +207,7 @@ gdk_wayland_toplevel_clear_saved_size (GdkWaylandToplevel *toplevel)
|
||||
|
||||
static void maybe_set_gtk_surface_dbus_properties (GdkWaylandToplevel *wayland_toplevel);
|
||||
static void maybe_set_gtk_surface_modal (GdkWaylandToplevel *wayland_toplevel);
|
||||
static gboolean maybe_set_xdg_dialog_modal (GdkWaylandToplevel *wayland_toplevel);
|
||||
|
||||
static void
|
||||
gdk_wayland_toplevel_hide_surface (GdkWaylandSurface *wayland_surface)
|
||||
@@ -215,6 +218,7 @@ gdk_wayland_toplevel_hide_surface (GdkWaylandSurface *wayland_surface)
|
||||
|
||||
g_clear_pointer (&toplevel->display_server.xdg_toplevel, xdg_toplevel_destroy);
|
||||
g_clear_pointer (&toplevel->display_server.zxdg_toplevel_v6, zxdg_toplevel_v6_destroy);
|
||||
g_clear_pointer (&toplevel->display_server.xdg_dialog, xdg_dialog_v1_destroy);
|
||||
|
||||
if (toplevel->display_server.gtk_surface)
|
||||
{
|
||||
@@ -877,7 +881,8 @@ gdk_wayland_surface_create_xdg_toplevel (GdkWaylandToplevel *wayland_toplevel)
|
||||
gdk_wayland_toplevel_set_application_id (GDK_TOPLEVEL (wayland_toplevel), app_id);
|
||||
|
||||
maybe_set_gtk_surface_dbus_properties (wayland_toplevel);
|
||||
maybe_set_gtk_surface_modal (wayland_toplevel);
|
||||
if (!maybe_set_xdg_dialog_modal (wayland_toplevel))
|
||||
maybe_set_gtk_surface_modal (wayland_toplevel);
|
||||
|
||||
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "Wayland surface commit", NULL);
|
||||
wl_surface_commit (wayland_surface->display_server.wl_surface);
|
||||
@@ -1089,12 +1094,40 @@ maybe_set_gtk_surface_modal (GdkWaylandToplevel *wayland_toplevel)
|
||||
|
||||
}
|
||||
|
||||
static gboolean
|
||||
maybe_set_xdg_dialog_modal (GdkWaylandToplevel *wayland_toplevel)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland =
|
||||
GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (wayland_toplevel)));
|
||||
|
||||
if (!display_wayland->xdg_wm_dialog)
|
||||
return FALSE;
|
||||
if (!is_realized_toplevel (GDK_WAYLAND_SURFACE (wayland_toplevel)))
|
||||
return FALSE;
|
||||
|
||||
if (!wayland_toplevel->display_server.xdg_dialog)
|
||||
{
|
||||
wayland_toplevel->display_server.xdg_dialog =
|
||||
xdg_wm_dialog_v1_get_xdg_dialog (display_wayland->xdg_wm_dialog,
|
||||
wayland_toplevel->display_server.xdg_toplevel);
|
||||
}
|
||||
|
||||
if (GDK_SURFACE (wayland_toplevel)->modal_hint)
|
||||
xdg_dialog_v1_set_modal (wayland_toplevel->display_server.xdg_dialog);
|
||||
else
|
||||
xdg_dialog_v1_unset_modal (wayland_toplevel->display_server.xdg_dialog);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_toplevel_set_modal_hint (GdkWaylandToplevel *wayland_toplevel,
|
||||
gboolean modal)
|
||||
{
|
||||
GDK_SURFACE (wayland_toplevel)->modal_hint = modal;
|
||||
maybe_set_gtk_surface_modal (wayland_toplevel);
|
||||
|
||||
if (!maybe_set_xdg_dialog_modal (wayland_toplevel))
|
||||
maybe_set_gtk_surface_modal (wayland_toplevel);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+121
-24
@@ -48,36 +48,133 @@ gdk_wayland_deps = [
|
||||
wlegldep,
|
||||
]
|
||||
|
||||
wlmod = import('unstable-wayland')
|
||||
# Fields:
|
||||
# - name: protocol name
|
||||
# - stability: protocol stability ('private', 'stable' or 'unstable')
|
||||
# - version: protocol version
|
||||
# - required: wayland_protocols version check
|
||||
proto_sources = [
|
||||
'protocol/gtk-shell.xml',
|
||||
'protocol/server-decoration.xml',
|
||||
wlmod.find_protocol('primary-selection', state: 'unstable', version: 1),
|
||||
wlmod.find_protocol('pointer-gestures', state: 'unstable', version: 1),
|
||||
wlmod.find_protocol('viewporter', state: 'stable'),
|
||||
wlmod.find_protocol('xdg-shell', state: 'unstable', version: 6),
|
||||
wlmod.find_protocol('xdg-shell', state: 'stable'),
|
||||
wlmod.find_protocol('xdg-foreign', state: 'unstable', version: 1),
|
||||
wlmod.find_protocol('xdg-foreign', state: 'unstable', version: 2),
|
||||
wlmod.find_protocol('tablet', state: 'unstable', version: 2),
|
||||
wlmod.find_protocol('keyboard-shortcuts-inhibit', state: 'unstable', version: 1),
|
||||
wlmod.find_protocol('xdg-output', state: 'unstable', version: 1),
|
||||
wlmod.find_protocol('idle-inhibit', state: 'unstable', version: 1),
|
||||
wlmod.find_protocol('xdg-activation', state: 'staging', version: 1),
|
||||
wlmod.find_protocol('fractional-scale', state: 'staging', version: 1),
|
||||
wlmod.find_protocol('linux-dmabuf', state: 'unstable', version: 1),
|
||||
wlmod.find_protocol('presentation-time', state: 'stable'),
|
||||
wlmod.find_protocol('single-pixel-buffer', state: 'staging', version: 1),
|
||||
{
|
||||
'name': 'gtk-shell',
|
||||
'stability': 'private',
|
||||
},
|
||||
{
|
||||
'name': 'primary-selection',
|
||||
'stability': 'unstable',
|
||||
'version': 1,
|
||||
},
|
||||
{
|
||||
'name': 'pointer-gestures',
|
||||
'stability': 'unstable',
|
||||
'version': 1,
|
||||
},
|
||||
{
|
||||
'name': 'viewporter',
|
||||
'stability': 'stable',
|
||||
},
|
||||
{
|
||||
'name': 'xdg-shell',
|
||||
'stability': 'unstable',
|
||||
'version': 6,
|
||||
},
|
||||
{
|
||||
'name': 'xdg-shell',
|
||||
'stability': 'stable',
|
||||
},
|
||||
{
|
||||
'name': 'xdg-foreign',
|
||||
'stability': 'unstable',
|
||||
'version': 1,
|
||||
},
|
||||
{
|
||||
'name': 'xdg-foreign',
|
||||
'stability': 'unstable',
|
||||
'version': 2,
|
||||
},
|
||||
{
|
||||
'name': 'tablet',
|
||||
'stability': 'unstable',
|
||||
'version': 2,
|
||||
},
|
||||
{
|
||||
'name': 'keyboard-shortcuts-inhibit',
|
||||
'stability': 'unstable',
|
||||
'version': 1,
|
||||
},
|
||||
{
|
||||
'name': 'server-decoration',
|
||||
'stability': 'private',
|
||||
},
|
||||
{
|
||||
'name': 'xdg-output',
|
||||
'stability': 'unstable',
|
||||
'version': 1,
|
||||
},
|
||||
{
|
||||
'name': 'idle-inhibit',
|
||||
'stability': 'unstable',
|
||||
'version': 1,
|
||||
},
|
||||
{
|
||||
'name': 'xdg-activation',
|
||||
'stability': 'staging',
|
||||
'version': 1,
|
||||
},
|
||||
{
|
||||
'name': 'fractional-scale',
|
||||
'stability': 'staging',
|
||||
'version': 1,
|
||||
},
|
||||
{
|
||||
'name': 'linux-dmabuf',
|
||||
'stability': 'unstable',
|
||||
'version': 1,
|
||||
},
|
||||
{
|
||||
'name': 'presentation-time',
|
||||
'stability': 'stable',
|
||||
'version': 1,
|
||||
},
|
||||
{
|
||||
'name': 'single-pixel-buffer',
|
||||
'stability': 'staging',
|
||||
'version': 1,
|
||||
},
|
||||
{
|
||||
'name': 'xdg-dialog',
|
||||
'stability': 'staging',
|
||||
'version': 1,
|
||||
},
|
||||
]
|
||||
|
||||
gdk_wayland_gen_headers = []
|
||||
|
||||
wlmod = import('unstable-wayland')
|
||||
foreach p: proto_sources
|
||||
# Returns a list [.c, .h]
|
||||
gen = wlmod.scan_xml(p)
|
||||
assert(gen.length() == 2)
|
||||
gdk_wayland_sources += gen[0]
|
||||
gdk_wayland_gen_headers += gen[1]
|
||||
if wlprotocolsdep.version().version_compare(p.get('required', '>=0'))
|
||||
if p.get('stability') == 'private'
|
||||
if (p.has_key('version'))
|
||||
proto_file = 'protocol/@0@-v@1@.xml'.format(p.get('name'), p.get('version'))
|
||||
else
|
||||
proto_file = 'protocol/@0@.xml'.format(p.get('name'))
|
||||
endif
|
||||
elif p.get('stability') == 'stable'
|
||||
proto_file = wlmod.find_protocol(p.get('name'),
|
||||
state: p.get('stability'),
|
||||
)
|
||||
else
|
||||
proto_file = wlmod.find_protocol(p.get('name'),
|
||||
state: p.get('stability'),
|
||||
version: p.get('version'),
|
||||
)
|
||||
endif
|
||||
|
||||
# Returns a list [.c, .h]
|
||||
gen = wlmod.scan_xml(proto_file)
|
||||
assert(gen.length() == 2)
|
||||
gdk_wayland_sources += gen[0]
|
||||
gdk_wayland_gen_headers += gen[1]
|
||||
endif
|
||||
endforeach
|
||||
|
||||
libgdk_wayland = static_library('gdk-wayland',
|
||||
|
||||
@@ -1408,7 +1408,7 @@ register_clipboard_notification ()
|
||||
WNDCLASS wclass = { 0, };
|
||||
ATOM klass;
|
||||
|
||||
wclass.lpszClassName = "GdkClipboardNotification";
|
||||
wclass.lpszClassName = L"GdkClipboardNotification";
|
||||
wclass.lpfnWndProc = _clipboard_window_procedure;
|
||||
wclass.hInstance = this_module ();
|
||||
wclass.cbWndExtra = sizeof (GdkWin32ClipboardThread *);
|
||||
@@ -1506,9 +1506,9 @@ gdk_win32_clipdrop_init (GdkWin32Clipdrop *win32_clipdrop)
|
||||
GdkWin32ContentFormatPair fmt;
|
||||
HMODULE user32;
|
||||
|
||||
thread_wakeup_message = RegisterWindowMessage ("GDK_WORKER_THREAD_WEAKEUP");
|
||||
thread_wakeup_message = RegisterWindowMessage (L"GDK_WORKER_THREAD_WEAKEUP");
|
||||
|
||||
user32 = LoadLibrary ("user32.dll");
|
||||
user32 = LoadLibrary (L"user32.dll");
|
||||
win32_clipdrop->GetUpdatedClipboardFormats = (GetUpdatedClipboardFormatsFunc) GetProcAddress (user32, "GetUpdatedClipboardFormats");
|
||||
FreeLibrary (user32);
|
||||
|
||||
@@ -1557,21 +1557,21 @@ gdk_win32_clipdrop_init (GdkWin32Clipdrop *win32_clipdrop)
|
||||
* the lead and map the GDK contentformat "image/png" to the clipboard
|
||||
* format name "PNG" etc.
|
||||
*/
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_PNG) = RegisterClipboardFormatA ("PNG");
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_JFIF) = RegisterClipboardFormatA ("JFIF");
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_GIF) = RegisterClipboardFormatA ("GIF");
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_PNG) = RegisterClipboardFormat (L"PNG");
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_JFIF) = RegisterClipboardFormat (L"JFIF");
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_GIF) = RegisterClipboardFormat (L"GIF");
|
||||
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_UNIFORMRESOURCELOCATORW) = RegisterClipboardFormatA ("UniformResourceLocatorW");
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_CFSTR_SHELLIDLIST) = RegisterClipboardFormatA (CFSTR_SHELLIDLIST);
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_HTML_FORMAT) = RegisterClipboardFormatA ("HTML Format");
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_TEXT_HTML) = RegisterClipboardFormatA ("text/html");
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_UNIFORMRESOURCELOCATORW) = RegisterClipboardFormat (L"UniformResourceLocatorW");
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_CFSTR_SHELLIDLIST) = RegisterClipboardFormat (CFSTR_SHELLIDLIST);
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_HTML_FORMAT) = RegisterClipboardFormat (L"HTML Format");
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_TEXT_HTML) = RegisterClipboardFormat (L"text/html");
|
||||
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_IMAGE_PNG) = RegisterClipboardFormatA ("image/png");
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_IMAGE_JPEG) = RegisterClipboardFormatA ("image/jpeg");
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_IMAGE_BMP) = RegisterClipboardFormatA ("image/bmp");
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_IMAGE_GIF) = RegisterClipboardFormatA ("image/gif");
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_TEXT_URI_LIST) = RegisterClipboardFormatA ("text/uri-list");
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_TEXT_PLAIN_UTF8) = RegisterClipboardFormatA ("text/plain;charset=utf-8");
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_IMAGE_PNG) = RegisterClipboardFormat (L"image/png");
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_IMAGE_JPEG) = RegisterClipboardFormat (L"image/jpeg");
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_IMAGE_BMP) = RegisterClipboardFormat (L"image/bmp");
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_IMAGE_GIF) = RegisterClipboardFormat (L"image/gif");
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_TEXT_URI_LIST) = RegisterClipboardFormat (L"text/uri-list");
|
||||
_gdk_cf_array_index (cfs, GDK_WIN32_CF_INDEX_TEXT_PLAIN_UTF8) = RegisterClipboardFormat (L"text/plain;charset=utf-8");
|
||||
|
||||
win32_clipdrop->active_source_drags = g_hash_table_new_full (NULL, NULL, (GDestroyNotify) g_object_unref, NULL);
|
||||
|
||||
@@ -2364,9 +2364,9 @@ transmute_cf_dib_to_image_bmp (const guchar *data,
|
||||
* check?
|
||||
*/
|
||||
(IsClipboardFormatAvailable
|
||||
(RegisterClipboardFormatA ("application/x-moz-nativeimage")) ||
|
||||
(RegisterClipboardFormat (L"application/x-moz-nativeimage")) ||
|
||||
IsClipboardFormatAvailable
|
||||
(RegisterClipboardFormatA ("UniformResourceLocatorW"))) &&
|
||||
(RegisterClipboardFormat (L"UniformResourceLocatorW"))) &&
|
||||
#endif
|
||||
TRUE)
|
||||
{
|
||||
|
||||
+36
-35
@@ -31,12 +31,13 @@
|
||||
|
||||
static struct {
|
||||
char *name;
|
||||
char *id;
|
||||
const wchar_t *id;
|
||||
} default_cursors[] = {
|
||||
/* -- Win32 cursor names: -- */
|
||||
{ "appstarting", IDC_APPSTARTING },
|
||||
{ "arrow", IDC_ARROW },
|
||||
{ "cross", IDC_CROSS },
|
||||
{ "dnd-move", IDC_ARROW },
|
||||
{ "hand", IDC_HAND },
|
||||
{ "help", IDC_HELP },
|
||||
{ "ibeam", IDC_IBEAM },
|
||||
@@ -456,32 +457,32 @@ win32_cursor_create_win32hcursor (GdkWin32Display *display,
|
||||
break;
|
||||
case GDK_WIN32_CURSOR_LOAD_FROM_RESOURCE_NULL:
|
||||
result = gdk_win32_hcursor_new (display,
|
||||
LoadImageA (NULL,
|
||||
(const char *) cursor->resource_name,
|
||||
IMAGE_CURSOR,
|
||||
cursor->width,
|
||||
cursor->height,
|
||||
cursor->load_flags),
|
||||
LoadImage (NULL,
|
||||
cursor->resource_name,
|
||||
IMAGE_CURSOR,
|
||||
cursor->width,
|
||||
cursor->height,
|
||||
cursor->load_flags),
|
||||
cursor->load_flags & LR_SHARED ? FALSE : TRUE);
|
||||
break;
|
||||
case GDK_WIN32_CURSOR_LOAD_FROM_RESOURCE_THIS:
|
||||
result = gdk_win32_hcursor_new (display,
|
||||
LoadImageA (GetModuleHandle (NULL),
|
||||
(const char *) cursor->resource_name,
|
||||
IMAGE_CURSOR,
|
||||
cursor->width,
|
||||
cursor->height,
|
||||
cursor->load_flags),
|
||||
LoadImage (GetModuleHandle (NULL),
|
||||
cursor->resource_name,
|
||||
IMAGE_CURSOR,
|
||||
cursor->width,
|
||||
cursor->height,
|
||||
cursor->load_flags),
|
||||
cursor->load_flags & LR_SHARED ? FALSE : TRUE);
|
||||
break;
|
||||
case GDK_WIN32_CURSOR_LOAD_FROM_RESOURCE_GTK:
|
||||
result = gdk_win32_hcursor_new (display,
|
||||
LoadImageA (this_module (),
|
||||
(const char *) cursor->resource_name,
|
||||
IMAGE_CURSOR,
|
||||
cursor->width,
|
||||
cursor->height,
|
||||
cursor->load_flags),
|
||||
LoadImage (this_module (),
|
||||
cursor->resource_name,
|
||||
IMAGE_CURSOR,
|
||||
cursor->width,
|
||||
cursor->height,
|
||||
cursor->load_flags),
|
||||
cursor->load_flags & LR_SHARED ? FALSE : TRUE);
|
||||
break;
|
||||
case GDK_WIN32_CURSOR_CREATE:
|
||||
@@ -498,12 +499,12 @@ win32_cursor_create_win32hcursor (GdkWin32Display *display,
|
||||
}
|
||||
|
||||
static Win32Cursor *
|
||||
win32_cursor_new (GdkWin32CursorLoadType load_type,
|
||||
gpointer resource_name,
|
||||
int width,
|
||||
int height,
|
||||
guint load_flags,
|
||||
int xcursor_number)
|
||||
win32_cursor_new (GdkWin32CursorLoadType load_type,
|
||||
wchar_t *resource_name,
|
||||
int width,
|
||||
int height,
|
||||
guint load_flags,
|
||||
int xcursor_number)
|
||||
{
|
||||
Win32Cursor *result;
|
||||
|
||||
@@ -631,9 +632,9 @@ win32_cursor_theme_load_system (Win32CursorTheme *theme,
|
||||
|
||||
/* Prefer W32 cursors */
|
||||
if (cursors[i].builtin)
|
||||
shared_hcursor = LoadImageA (NULL, cursors[i].builtin, IMAGE_CURSOR,
|
||||
size, size,
|
||||
LR_SHARED | (size == 0 ? LR_DEFAULTSIZE : 0));
|
||||
shared_hcursor = LoadImage (NULL, cursors[i].builtin, IMAGE_CURSOR,
|
||||
size, size,
|
||||
LR_SHARED | (size == 0 ? LR_DEFAULTSIZE : 0));
|
||||
|
||||
/* Fall back to X cursors, but only if we've got no theme cursor */
|
||||
if (shared_hcursor == NULL && g_hash_table_lookup (theme->named_cursors, cursors[i].name) == NULL)
|
||||
@@ -645,7 +646,7 @@ win32_cursor_theme_load_system (Win32CursorTheme *theme,
|
||||
DestroyCursor (x_hcursor);
|
||||
|
||||
cursor = win32_cursor_new (shared_hcursor ? GDK_WIN32_CURSOR_LOAD_FROM_RESOURCE_NULL : GDK_WIN32_CURSOR_CREATE,
|
||||
(gpointer) cursors[i].builtin,
|
||||
(wchar_t*) cursors[i].builtin,
|
||||
size,
|
||||
size,
|
||||
LR_SHARED | (size == 0 ? LR_DEFAULTSIZE : 0),
|
||||
@@ -660,14 +661,14 @@ win32_cursor_theme_load_system (Win32CursorTheme *theme,
|
||||
if (default_cursors[i].name == NULL)
|
||||
break;
|
||||
|
||||
shared_hcursor = LoadImageA (NULL, default_cursors[i].id, IMAGE_CURSOR, size, size,
|
||||
LR_SHARED | (size == 0 ? LR_DEFAULTSIZE : 0));
|
||||
shared_hcursor = LoadImage (NULL, default_cursors[i].id, IMAGE_CURSOR, size, size,
|
||||
LR_SHARED | (size == 0 ? LR_DEFAULTSIZE : 0));
|
||||
|
||||
if (shared_hcursor == NULL)
|
||||
continue;
|
||||
|
||||
cursor = win32_cursor_new (GDK_WIN32_CURSOR_LOAD_FROM_RESOURCE_NULL,
|
||||
(gpointer) default_cursors[i].id,
|
||||
(wchar_t*) default_cursors[i].id,
|
||||
size,
|
||||
size,
|
||||
LR_SHARED | (size == 0 ? LR_DEFAULTSIZE : 0),
|
||||
@@ -779,8 +780,8 @@ win32hcursor_idc_from_name (GdkWin32Display *display,
|
||||
continue;
|
||||
|
||||
return gdk_win32_hcursor_new (display,
|
||||
LoadImageA (NULL, default_cursors[i].id, IMAGE_CURSOR, 0, 0,
|
||||
LR_SHARED | LR_DEFAULTSIZE),
|
||||
LoadImage (NULL, default_cursors[i].id, IMAGE_CURSOR, 0, 0,
|
||||
LR_SHARED | LR_DEFAULTSIZE),
|
||||
FALSE);
|
||||
}
|
||||
|
||||
@@ -884,7 +885,7 @@ gdk_win32hcursor_create_for_name (GdkWin32Display *display,
|
||||
/* Allow to load named cursor resources linked into the executable.
|
||||
* Cursors obtained with LoadCursor() cannot be destroyed.
|
||||
*/
|
||||
return gdk_win32_hcursor_new (display, LoadCursor (hinstance, name), FALSE);
|
||||
return gdk_win32_hcursor_new (display, LoadCursorA (hinstance, name), FALSE);
|
||||
}
|
||||
|
||||
static HICON
|
||||
|
||||
@@ -121,7 +121,7 @@ gdk_device_manager_win32_finalize (GObject *object)
|
||||
#if DEBUG_WINTAB
|
||||
|
||||
static void
|
||||
print_lc(LOGCONTEXT *lc)
|
||||
print_lc(LOGCONTEXTA *lc)
|
||||
{
|
||||
g_print ("lcName = %s\n", lc->lcName);
|
||||
g_print ("lcOptions =");
|
||||
@@ -374,13 +374,13 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
|
||||
|
||||
wintab_contexts = NULL;
|
||||
|
||||
n = GetSystemDirectory (&dummy, 0);
|
||||
n = GetSystemDirectoryA (&dummy, 0);
|
||||
|
||||
if (n <= 0)
|
||||
return;
|
||||
|
||||
wintab32_dll_path = g_malloc (n + 1 + strlen (WINTAB32_DLL));
|
||||
k = GetSystemDirectory (wintab32_dll_path, n);
|
||||
k = GetSystemDirectoryA (wintab32_dll_path, n);
|
||||
|
||||
if (k == 0 || k > n)
|
||||
{
|
||||
@@ -392,7 +392,7 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
|
||||
strcat (wintab32_dll_path, G_DIR_SEPARATOR_S);
|
||||
strcat (wintab32_dll_path, WINTAB32_DLL);
|
||||
|
||||
if ((wintab32 = LoadLibrary (wintab32_dll_path)) == NULL)
|
||||
if ((wintab32 = LoadLibraryA (wintab32_dll_path)) == NULL)
|
||||
return;
|
||||
|
||||
if ((p_WTInfoA = (t_WTInfoA) GetProcAddress (wintab32, "WTInfoA")) == NULL)
|
||||
@@ -433,7 +433,7 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
|
||||
|
||||
for (devix = 0; devix < ndevices; devix++)
|
||||
{
|
||||
LOGCONTEXT lc;
|
||||
LOGCONTEXTA lc;
|
||||
|
||||
/* We open the Wintab device (hmm, what if there are several, or
|
||||
* can there even be several, probably not?) as a system
|
||||
|
||||
@@ -480,7 +480,7 @@ register_display_change_notification (GdkDisplay *display)
|
||||
WNDCLASS wclass = { 0, };
|
||||
ATOM klass;
|
||||
|
||||
wclass.lpszClassName = "GdkDisplayChange";
|
||||
wclass.lpszClassName = L"GdkDisplayChange";
|
||||
wclass.lpfnWndProc = display_change_window_procedure;
|
||||
wclass.hInstance = this_module ();
|
||||
wclass.style = CS_OWNDC;
|
||||
@@ -606,7 +606,7 @@ gdk_win32_display_get_name (GdkDisplay *display)
|
||||
window_station_name = "WinSta0";
|
||||
}
|
||||
|
||||
processIdToSessionId = (PFN_ProcessIdToSessionId) GetProcAddress (GetModuleHandle ("kernel32.dll"), "ProcessIdToSessionId");
|
||||
processIdToSessionId = (PFN_ProcessIdToSessionId) GetProcAddress (GetModuleHandle (L"kernel32.dll"), "ProcessIdToSessionId");
|
||||
if (!processIdToSessionId || !processIdToSessionId (GetCurrentProcessId (), &session_id))
|
||||
session_id = 0;
|
||||
|
||||
|
||||
@@ -134,6 +134,7 @@ struct _GdkWin32Display
|
||||
guint hasWglEXTSwapControl : 1;
|
||||
guint hasWglOMLSyncControl : 1;
|
||||
guint hasWglARBPixelFormat : 1;
|
||||
guint force_enable_depth_bits : 1;
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
guint hasEglKHRCreateContext : 1;
|
||||
|
||||
@@ -658,7 +658,7 @@ _gdk_win32_dnd_thread_main (gpointer data)
|
||||
/* Create a message queue */
|
||||
PeekMessage (&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
|
||||
|
||||
thread_wakeup_message = RegisterWindowMessage ("GDK_WORKER_THREAD_WEAKEUP");
|
||||
thread_wakeup_message = RegisterWindowMessage (L"GDK_WORKER_THREAD_WEAKEUP");
|
||||
|
||||
/* Signal the main thread that we're ready.
|
||||
* This is the only time the queue works in reverse.
|
||||
|
||||
@@ -419,7 +419,7 @@ set_up_low_level_keyboard_hook (void)
|
||||
else
|
||||
WIN32_API_FAILED ("SetWindowsHookEx");
|
||||
|
||||
aerosnap_message = RegisterWindowMessage ("GDK_WIN32_AEROSNAP_MESSAGE");
|
||||
aerosnap_message = RegisterWindowMessage (L"GDK_WIN32_AEROSNAP_MESSAGE");
|
||||
}
|
||||
|
||||
void
|
||||
@@ -470,7 +470,7 @@ _gdk_events_init (GdkDisplay *display)
|
||||
};
|
||||
#endif
|
||||
|
||||
got_gdk_events_message = RegisterWindowMessage ("GDK_WIN32_GOT_EVENTS");
|
||||
got_gdk_events_message = RegisterWindowMessage (L"GDK_WIN32_GOT_EVENTS");
|
||||
|
||||
#if 0
|
||||
/* Check if we have some input locale identifier loaded that uses a
|
||||
@@ -1685,7 +1685,7 @@ _gdk_win32_surface_fill_min_max_info (GdkSurface *window,
|
||||
nearest_monitor = MonitorFromWindow (GDK_SURFACE_HWND (window), MONITOR_DEFAULTTONEAREST);
|
||||
nearest_info.cbSize = sizeof (nearest_info);
|
||||
|
||||
if (GetMonitorInfoA (nearest_monitor, &nearest_info))
|
||||
if (GetMonitorInfo (nearest_monitor, &nearest_info))
|
||||
{
|
||||
/* MSDN says that we must specify maximized window
|
||||
* size as if it was located on the primary monitor.
|
||||
|
||||
@@ -142,8 +142,7 @@ get_wgl_pfd (HDC hdc,
|
||||
|
||||
pfd->nSize = sizeof (PIXELFORMATDESCRIPTOR);
|
||||
|
||||
if (display_win32 != NULL &&
|
||||
display_win32->hasWglARBPixelFormat)
|
||||
if (display_win32->hasWglARBPixelFormat)
|
||||
{
|
||||
UINT num_formats;
|
||||
int colorbits = GetDeviceCaps (hdc, BITSPIXEL);
|
||||
@@ -176,15 +175,18 @@ get_wgl_pfd (HDC hdc,
|
||||
pixelAttribs[i++] = WGL_ALPHA_BITS_ARB;
|
||||
pixelAttribs[i++] = 8;
|
||||
|
||||
pixelAttribs[i++] = WGL_DEPTH_BITS_ARB;
|
||||
pixelAttribs[i++] = 0;
|
||||
|
||||
pixelAttribs[i++] = WGL_STENCIL_BITS_ARB;
|
||||
pixelAttribs[i++] = 0;
|
||||
|
||||
pixelAttribs[i++] = WGL_ACCUM_BITS_ARB;
|
||||
pixelAttribs[i++] = 0;
|
||||
|
||||
if (!display_win32->force_enable_depth_bits)
|
||||
{
|
||||
pixelAttribs[i++] = WGL_DEPTH_BITS_ARB;
|
||||
pixelAttribs[i++] = 0;
|
||||
}
|
||||
|
||||
/* end of "Update PIXEL_ATTRIBUTES above if any groups are added here!" */
|
||||
|
||||
pixelAttribs[i++] = 0; /* end of pixelAttribs */
|
||||
@@ -215,8 +217,20 @@ get_wgl_pfd (HDC hdc,
|
||||
pfd->cColorBits = GetDeviceCaps (hdc, BITSPIXEL);
|
||||
pfd->cAlphaBits = 8;
|
||||
pfd->iLayerType = PFD_MAIN_PLANE;
|
||||
pfd->cAccumBits = 0;
|
||||
pfd->cStencilBits = 0;
|
||||
|
||||
if (!display_win32->force_enable_depth_bits)
|
||||
pfd->cDepthBits = 0;
|
||||
|
||||
best_pf = ChoosePixelFormat (hdc, pfd);
|
||||
|
||||
/* try again if driver enforces depth buffers */
|
||||
if (best_pf == 0 && !display_win32->force_enable_depth_bits)
|
||||
{
|
||||
display_win32->force_enable_depth_bits = TRUE;
|
||||
get_wgl_pfd (hdc, pfd, display_win32);
|
||||
}
|
||||
}
|
||||
|
||||
return best_pf;
|
||||
@@ -234,7 +248,7 @@ gdk_init_dummy_wgl_context (GdkWin32Display *display_win32)
|
||||
|
||||
memset (&pfd, 0, sizeof (PIXELFORMATDESCRIPTOR));
|
||||
|
||||
best_idx = get_wgl_pfd (display_win32->dummy_context_wgl.hdc, &pfd, NULL);
|
||||
best_idx = get_wgl_pfd (display_win32->dummy_context_wgl.hdc, &pfd, display_win32);
|
||||
|
||||
if (best_idx != 0)
|
||||
set_pixel_format_result = SetPixelFormat (display_win32->dummy_context_wgl.hdc,
|
||||
@@ -269,7 +283,7 @@ create_dummy_gl_window (void)
|
||||
ATOM klass;
|
||||
HWND hwnd = NULL;
|
||||
|
||||
wclass.lpszClassName = "GdkGLDummyWindow";
|
||||
wclass.lpszClassName = L"GdkGLDummyWindow";
|
||||
wclass.lpfnWndProc = DefWindowProc;
|
||||
wclass.hInstance = this_module ();
|
||||
wclass.style = CS_OWNDC;
|
||||
|
||||
@@ -730,7 +730,7 @@ _gdk_win32_key_to_string (LONG lParam)
|
||||
char buf[100];
|
||||
char *keyname_utf8;
|
||||
|
||||
if (GetKeyNameText (lParam, buf, sizeof (buf)) &&
|
||||
if (GetKeyNameTextA (lParam, buf, sizeof (buf)) &&
|
||||
(keyname_utf8 = g_locale_to_utf8 (buf, -1, NULL, NULL, NULL)) != NULL)
|
||||
{
|
||||
char *retval = static_printf ("%s", keyname_utf8);
|
||||
@@ -780,7 +780,7 @@ _gdk_win32_cf_to_string (UINT format)
|
||||
if (format >= CF_PRIVATEFIRST &&
|
||||
format <= CF_PRIVATELAST)
|
||||
return static_printf ("CF_PRIVATE%d", format - CF_PRIVATEFIRST);
|
||||
if (GetClipboardFormatName (format, buf, sizeof (buf)))
|
||||
if (GetClipboardFormatNameA (format, buf, sizeof (buf)))
|
||||
return static_printf ("'%s'", buf);
|
||||
else
|
||||
return static_printf ("unk-%#lx", format);
|
||||
|
||||
@@ -197,7 +197,7 @@ typedef struct _Win32Cursor Win32Cursor;
|
||||
|
||||
struct _Win32Cursor {
|
||||
GdkWin32CursorLoadType load_type;
|
||||
gunichar2 *resource_name;
|
||||
wchar_t *resource_name;
|
||||
int width;
|
||||
int height;
|
||||
guint load_flags;
|
||||
|
||||
@@ -326,7 +326,7 @@ RegisterGdkClass (GType wtype)
|
||||
static WNDCLASSEXW wcl;
|
||||
ATOM klass = 0;
|
||||
|
||||
wcl.cbSize = sizeof (WNDCLASSEX);
|
||||
wcl.cbSize = sizeof (WNDCLASSEXW);
|
||||
wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
|
||||
* on WM_SIZE and WM_MOVE. Flicker, Performance!
|
||||
*/
|
||||
@@ -340,7 +340,7 @@ RegisterGdkClass (GType wtype)
|
||||
/* initialize once! */
|
||||
if (0 == hAppIcon && 0 == hAppIconSm)
|
||||
{
|
||||
char sLoc [MAX_PATH+1];
|
||||
wchar_t sLoc [MAX_PATH+1];
|
||||
|
||||
// try to load first icon of executable program
|
||||
if (0 != GetModuleFileName (NULL, sLoc, MAX_PATH))
|
||||
@@ -2064,7 +2064,7 @@ stash_window (GdkSurface *window,
|
||||
hmonitor = MonitorFromWindow (GDK_SURFACE_HWND (window), MONITOR_DEFAULTTONEAREST);
|
||||
hmonitor_info.cbSize = sizeof (hmonitor_info);
|
||||
|
||||
if (!GetMonitorInfoA (hmonitor, &hmonitor_info))
|
||||
if (!GetMonitorInfo (hmonitor, &hmonitor_info))
|
||||
return;
|
||||
|
||||
if (impl->snap_stash == NULL)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
static const struct { const char *name; const char *builtin; int type; guchar width; guchar height; guchar hotx; guchar hoty; char *data; } cursors[] = {
|
||||
static const struct { const char *name; const wchar_t *builtin; int type; guchar width; guchar height; guchar hotx; guchar hoty; char *data; } cursors[] = {
|
||||
{ "X_cursor", NULL, 0, 16, 16, 7, 7,
|
||||
"\125\000\000\125\152\100\001\251\152\220\006\251\152\244\032\251"
|
||||
"\032\251\152\244\006\252\252\220\001\252\252\100\000\152\251\000"
|
||||
|
||||
@@ -127,7 +127,7 @@ gsk_gl_glyph_library_init_atlas (GskGLTextureLibrary *self,
|
||||
else
|
||||
{
|
||||
gl_format = GL_BGRA;
|
||||
gl_type = GL_UNSIGNED_BYTE;
|
||||
gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
}
|
||||
glBindTexture (GL_TEXTURE_2D, atlas->texture_id);
|
||||
|
||||
@@ -293,7 +293,7 @@ gsk_gl_glyph_library_upload_glyph (GskGLGlyphLibrary *self,
|
||||
{
|
||||
pixel_data = cairo_image_surface_get_data (surface);
|
||||
gl_format = GL_BGRA;
|
||||
gl_type = GL_UNSIGNED_BYTE;
|
||||
gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
}
|
||||
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, stride / 4);
|
||||
|
||||
@@ -125,7 +125,7 @@ gsk_gl_icon_library_add (GskGLIconLibrary *self,
|
||||
{
|
||||
pixel_data = surface_data;
|
||||
gl_format = GL_BGRA;
|
||||
gl_type = GL_UNSIGNED_BYTE;
|
||||
gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
}
|
||||
|
||||
texture_id = GSK_GL_TEXTURE_ATLAS_ENTRY_TEXTURE (icon_data);
|
||||
|
||||
@@ -41,6 +41,15 @@
|
||||
#include <gsk/gskroundedrectprivate.h>
|
||||
#include <gsk/gskrectprivate.h>
|
||||
|
||||
/**
|
||||
* GskGLRenderer:
|
||||
*
|
||||
* A GL based renderer.
|
||||
*
|
||||
* See [class@Gsk.Renderer].
|
||||
*
|
||||
* Since: 4.2
|
||||
*/
|
||||
struct _GskGLRendererClass
|
||||
{
|
||||
GskRendererClass parent_class;
|
||||
|
||||
@@ -70,7 +70,10 @@ gsk_gl_frame_cleanup (GskGpuFrame *frame)
|
||||
if (self->sync)
|
||||
{
|
||||
glClientWaitSync (self->sync, 0, -1);
|
||||
g_clear_pointer (&self->sync, glDeleteSync);
|
||||
|
||||
/* can't use g_clear_pointer() on glDeleteSync(), see MR !7294 */
|
||||
glDeleteSync (self->sync);
|
||||
self->sync = NULL;
|
||||
}
|
||||
|
||||
self->next_texture_slot = 0;
|
||||
|
||||
@@ -249,7 +249,13 @@ gsk_gl_texture_data_free (gpointer user_data)
|
||||
|
||||
gdk_gl_context_make_current (data->context);
|
||||
|
||||
g_clear_pointer (&data->sync, glDeleteSync);
|
||||
/* can't use g_clear_pointer() on glDeleteSync(), see MR !7294 */
|
||||
if (data->sync)
|
||||
{
|
||||
glDeleteSync (data->sync);
|
||||
data->sync = NULL;
|
||||
}
|
||||
|
||||
glDeleteTextures (1, &data->texture_id);
|
||||
g_object_unref (data->context);
|
||||
|
||||
|
||||
@@ -13,6 +13,15 @@
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
/**
|
||||
* GskNglRenderer:
|
||||
*
|
||||
* A GL based renderer.
|
||||
*
|
||||
* See [class@Gsk.Renderer].
|
||||
*
|
||||
* Since: 4.2
|
||||
*/
|
||||
struct _GskNglRenderer
|
||||
{
|
||||
GskGpuRenderer parent_instance;
|
||||
|
||||
+24
-11
@@ -81,6 +81,7 @@ struct _PipelineCacheKey
|
||||
GskGpuShaderClip clip;
|
||||
GskGpuBlend blend;
|
||||
VkFormat format;
|
||||
VkPipeline pipeline;
|
||||
};
|
||||
|
||||
struct _RenderPassCacheKey
|
||||
@@ -88,6 +89,7 @@ struct _RenderPassCacheKey
|
||||
VkFormat format;
|
||||
VkImageLayout from_layout;
|
||||
VkImageLayout to_layout;
|
||||
VkRenderPass render_pass;
|
||||
};
|
||||
|
||||
static guint
|
||||
@@ -297,8 +299,10 @@ gsk_vulkan_pipeline_layout_unref (GskVulkanDevice *self,
|
||||
g_hash_table_iter_init (&iter, layout->pipeline_cache);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
vkDestroyPipeline (display->vk_device,
|
||||
((PipelineCacheKey *)key)->pipeline,
|
||||
NULL);
|
||||
g_free (key);
|
||||
vkDestroyPipeline (display->vk_device, value, NULL);
|
||||
}
|
||||
g_hash_table_unref (layout->pipeline_cache);
|
||||
|
||||
@@ -463,8 +467,10 @@ gsk_vulkan_device_finalize (GObject *object)
|
||||
g_hash_table_iter_init (&iter, self->render_pass_cache);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
vkDestroyRenderPass (display->vk_device,
|
||||
((RenderPassCacheKey *)key)->render_pass,
|
||||
NULL);
|
||||
g_free (key);
|
||||
vkDestroyRenderPass (display->vk_device, value, NULL);
|
||||
}
|
||||
g_hash_table_unref (self->render_pass_cache);
|
||||
|
||||
@@ -824,6 +830,7 @@ gsk_vulkan_device_get_vk_render_pass (GskVulkanDevice *self,
|
||||
VkImageLayout to_layout)
|
||||
{
|
||||
RenderPassCacheKey cache_key;
|
||||
RenderPassCacheKey *cached_result;
|
||||
VkRenderPass render_pass;
|
||||
GdkDisplay *display;
|
||||
|
||||
@@ -832,9 +839,9 @@ gsk_vulkan_device_get_vk_render_pass (GskVulkanDevice *self,
|
||||
.from_layout = from_layout,
|
||||
.to_layout = to_layout,
|
||||
};
|
||||
render_pass = g_hash_table_lookup (self->render_pass_cache, &cache_key);
|
||||
if (render_pass)
|
||||
return render_pass;
|
||||
cached_result = g_hash_table_lookup (self->render_pass_cache, &cache_key);
|
||||
if (cached_result)
|
||||
return cached_result->render_pass;
|
||||
|
||||
display = gsk_gpu_device_get_display (GSK_GPU_DEVICE (self));
|
||||
|
||||
@@ -878,7 +885,10 @@ gsk_vulkan_device_get_vk_render_pass (GskVulkanDevice *self,
|
||||
NULL,
|
||||
&render_pass);
|
||||
|
||||
g_hash_table_insert (self->render_pass_cache, g_memdup (&cache_key, sizeof (RenderPassCacheKey)), render_pass);
|
||||
cached_result = g_memdup (&cache_key, sizeof (RenderPassCacheKey));
|
||||
cached_result->render_pass = render_pass;
|
||||
|
||||
g_hash_table_insert (self->render_pass_cache, cached_result, cached_result);
|
||||
|
||||
return render_pass;
|
||||
}
|
||||
@@ -946,6 +956,7 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
|
||||
VkRenderPass render_pass)
|
||||
{
|
||||
PipelineCacheKey cache_key;
|
||||
PipelineCacheKey *cached_result;
|
||||
VkPipeline pipeline;
|
||||
GdkDisplay *display;
|
||||
const char *version_string;
|
||||
@@ -961,9 +972,9 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
|
||||
.blend = blend,
|
||||
.format = format,
|
||||
};
|
||||
pipeline = g_hash_table_lookup (layout->pipeline_cache, &cache_key);
|
||||
if (pipeline)
|
||||
return pipeline;
|
||||
cached_result = g_hash_table_lookup (layout->pipeline_cache, &cache_key);
|
||||
if (cached_result)
|
||||
return cached_result->pipeline;
|
||||
|
||||
display = gsk_gpu_device_get_display (GSK_GPU_DEVICE (self));
|
||||
if (gsk_vulkan_device_has_feature (self, GDK_VULKAN_FEATURE_DYNAMIC_INDEXING) &&
|
||||
@@ -1153,7 +1164,9 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
|
||||
g_free (fragment_shader_name);
|
||||
g_free (vertex_shader_name);
|
||||
|
||||
g_hash_table_insert (layout->pipeline_cache, g_memdup (&cache_key, sizeof (PipelineCacheKey)), pipeline);
|
||||
cached_result = g_memdup (&cache_key, sizeof (PipelineCacheKey));
|
||||
cached_result->pipeline = pipeline;
|
||||
g_hash_table_insert (layout->pipeline_cache, cached_result, cached_result);
|
||||
gdk_display_vulkan_pipeline_cache_updated (display);
|
||||
|
||||
return pipeline;
|
||||
@@ -1261,7 +1274,7 @@ gsk_vulkan_device_find_allocator (GskVulkanDevice *self,
|
||||
|
||||
g_assert (found < properties.memoryTypeCount);
|
||||
|
||||
return gsk_vulkan_allocator_ref (gsk_vulkan_device_get_allocator (self, i, &properties.memoryTypes[i]));
|
||||
return gsk_vulkan_allocator_ref (gsk_vulkan_device_get_allocator (self, found, &properties.memoryTypes[found]));
|
||||
}
|
||||
|
||||
GskVulkanAllocator *
|
||||
|
||||
@@ -178,7 +178,7 @@ gsk_vulkan_buddy_allocator_alloc (GskVulkanAllocator *allocator,
|
||||
if (self->cache.vk_memory)
|
||||
{
|
||||
*alloc = self->cache;
|
||||
self->cache.vk_memory = NULL;
|
||||
self->cache.vk_memory = VK_NULL_HANDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -240,7 +240,7 @@ restart:
|
||||
alloc->size <<= 1;
|
||||
if (slot == 0)
|
||||
{
|
||||
if (self->cache.vk_memory == NULL)
|
||||
if (self->cache.vk_memory == VK_NULL_HANDLE)
|
||||
self->cache = *alloc;
|
||||
else
|
||||
gsk_vulkan_free (self->allocator, alloc);
|
||||
|
||||
+1
-1
@@ -439,7 +439,7 @@ gsk_gl_shader_class_init (GskGLShaderClass *klass)
|
||||
object_class->constructed = gsk_gl_shader_constructed;
|
||||
|
||||
/**
|
||||
* GskGLShader:sourcecode: (attributes org.gtk.Property.get=gsk_gl_shader_get_source)
|
||||
* GskGLShader:source: (attributes org.gtk.Property.get=gsk_gl_shader_get_source)
|
||||
*
|
||||
* The source code for the shader, as a `GBytes`.
|
||||
*/
|
||||
|
||||
@@ -387,6 +387,7 @@ gsk_path_builder_add_reverse_path (GskPathBuilder *self,
|
||||
/**
|
||||
* gsk_path_builder_add_cairo_path:
|
||||
* @self: a `GskPathBuilder`
|
||||
* @path: a path
|
||||
*
|
||||
* Adds a Cairo path to the builder.
|
||||
*
|
||||
|
||||
@@ -51,6 +51,16 @@ G_DEFINE_BOXED_TYPE (GskPathPoint, gsk_path_point,
|
||||
gsk_path_point_copy,
|
||||
gsk_path_point_free)
|
||||
|
||||
/**
|
||||
* gsk_path_point_copy:
|
||||
* @point: a path point
|
||||
*
|
||||
* Copies a path point.
|
||||
*
|
||||
* Returns: the copied point
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
GskPathPoint *
|
||||
gsk_path_point_copy (GskPathPoint *point)
|
||||
{
|
||||
@@ -63,6 +73,14 @@ gsk_path_point_copy (GskPathPoint *point)
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_path_point_free:
|
||||
* @point: a path point
|
||||
*
|
||||
* Frees a path point copied by [method@Gsk.PathPoint.copy].
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
void
|
||||
gsk_path_point_free (GskPathPoint *point)
|
||||
{
|
||||
|
||||
+10
-3
@@ -679,9 +679,16 @@ vulkan_supported_platform (GdkSurface *surface,
|
||||
if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU)
|
||||
{
|
||||
if (!as_fallback)
|
||||
GSK_DEBUG (RENDERER,
|
||||
"Not using '%s': device is CPU",
|
||||
g_type_name (renderer_type));
|
||||
GSK_DEBUG (RENDERER, "Not using '%s': device is CPU", g_type_name (renderer_type));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gdk_display_init_dmabuf (display);
|
||||
if (!display->vk_dmabuf_formats ||
|
||||
gdk_dmabuf_formats_get_n_formats (display->vk_dmabuf_formats) == 0)
|
||||
{
|
||||
if (!as_fallback)
|
||||
GSK_DEBUG (RENDERER, "Not using '%s': no dmabuf support", g_type_name (renderer_type));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,13 @@
|
||||
|
||||
#include <gobject/gvaluecollector.h>
|
||||
|
||||
/**
|
||||
* gsk_serialization_error_quark:
|
||||
*
|
||||
* Registers an error quark for [class@Gsk.RenderNode] errors.
|
||||
*
|
||||
* Returns: the error quark
|
||||
**/
|
||||
G_DEFINE_QUARK (gsk-serialization-error-quark, gsk_serialization_error)
|
||||
|
||||
#define GSK_RENDER_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_RENDER_NODE, GskRenderNodeClass))
|
||||
|
||||
+184
-123
@@ -54,6 +54,8 @@
|
||||
#include <pango/pangofc-fontmap.h>
|
||||
#endif
|
||||
|
||||
#include <hb-subset.h>
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
typedef struct _Context Context;
|
||||
@@ -946,23 +948,22 @@ create_ascii_glyphs (PangoFont *font)
|
||||
PangoGlyphString *result, *glyph_string;
|
||||
guint i;
|
||||
|
||||
coverage = pango_font_get_coverage (font, language);
|
||||
for (i = MIN_ASCII_GLYPH; i < MAX_ASCII_GLYPH; i++)
|
||||
{
|
||||
if (!pango_coverage_get (coverage, i))
|
||||
break;
|
||||
}
|
||||
g_object_unref (coverage);
|
||||
if (i < MAX_ASCII_GLYPH)
|
||||
return NULL;
|
||||
|
||||
result = pango_glyph_string_new ();
|
||||
|
||||
coverage = pango_font_get_coverage (font, language);
|
||||
|
||||
pango_glyph_string_set_size (result, N_ASCII_GLYPHS);
|
||||
glyph_string = pango_glyph_string_new ();
|
||||
for (i = MIN_ASCII_GLYPH; i < MAX_ASCII_GLYPH; i++)
|
||||
{
|
||||
const char text[2] = { i, 0 };
|
||||
|
||||
if (!pango_coverage_get (coverage, i))
|
||||
{
|
||||
result->glyphs[i - MIN_ASCII_GLYPH].glyph = PANGO_GLYPH_INVALID_INPUT;
|
||||
continue;
|
||||
}
|
||||
|
||||
pango_shape_with_flags (text, 1,
|
||||
text, 1,
|
||||
¬_a_hack,
|
||||
@@ -970,14 +971,13 @@ create_ascii_glyphs (PangoFont *font)
|
||||
PANGO_SHAPE_NONE);
|
||||
|
||||
if (glyph_string->num_glyphs != 1)
|
||||
{
|
||||
pango_glyph_string_free (glyph_string);
|
||||
pango_glyph_string_free (result);
|
||||
return NULL;
|
||||
}
|
||||
result->glyphs[i - MIN_ASCII_GLYPH] = glyph_string->glyphs[0];
|
||||
result->glyphs[i - MIN_ASCII_GLYPH].glyph = PANGO_GLYPH_INVALID_INPUT;
|
||||
else
|
||||
result->glyphs[i - MIN_ASCII_GLYPH] = glyph_string->glyphs[0];
|
||||
}
|
||||
|
||||
g_object_unref (coverage);
|
||||
|
||||
pango_glyph_string_free (glyph_string);
|
||||
|
||||
return result;
|
||||
@@ -1113,81 +1113,70 @@ parse_font (GtkCssParser *parser,
|
||||
if (font_name == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (context->fontmap)
|
||||
font = font_from_string (context->fontmap, font_name, FALSE);
|
||||
|
||||
if (gtk_css_parser_has_url (parser))
|
||||
{
|
||||
char *url;
|
||||
char *scheme;
|
||||
GBytes *bytes;
|
||||
GError *error = NULL;
|
||||
GtkCssLocation start_location;
|
||||
gboolean success = FALSE;
|
||||
|
||||
if (font != NULL)
|
||||
start_location = *gtk_css_parser_get_start_location (parser);
|
||||
url = gtk_css_parser_consume_url (parser);
|
||||
|
||||
if (url != NULL)
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "A font with this name already exists.");
|
||||
/* consume the url to avoid more errors */
|
||||
url = gtk_css_parser_consume_url (parser);
|
||||
g_free (url);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *scheme;
|
||||
GBytes *bytes;
|
||||
GError *error = NULL;
|
||||
GtkCssLocation start_location;
|
||||
gboolean success = FALSE;
|
||||
|
||||
start_location = *gtk_css_parser_get_start_location (parser);
|
||||
url = gtk_css_parser_consume_url (parser);
|
||||
|
||||
if (url != NULL)
|
||||
scheme = g_uri_parse_scheme (url);
|
||||
if (scheme && g_ascii_strcasecmp (scheme, "data") == 0)
|
||||
{
|
||||
scheme = g_uri_parse_scheme (url);
|
||||
if (scheme && g_ascii_strcasecmp (scheme, "data") == 0)
|
||||
{
|
||||
bytes = gtk_css_data_url_parse (url, NULL, &error);
|
||||
}
|
||||
else
|
||||
{
|
||||
GFile *file;
|
||||
bytes = gtk_css_data_url_parse (url, NULL, &error);
|
||||
}
|
||||
else
|
||||
{
|
||||
GFile *file;
|
||||
|
||||
file = g_file_new_for_uri (url);
|
||||
bytes = g_file_load_bytes (file, NULL, NULL, &error);
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
g_free (scheme);
|
||||
g_free (url);
|
||||
if (bytes != NULL)
|
||||
{
|
||||
success = add_font_from_bytes (context, bytes, &error);
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
gtk_css_parser_emit_error (parser,
|
||||
&start_location,
|
||||
gtk_css_parser_get_end_location (parser),
|
||||
error);
|
||||
}
|
||||
file = g_file_new_for_uri (url);
|
||||
bytes = g_file_load_bytes (file, NULL, NULL, &error);
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
if (success)
|
||||
g_free (scheme);
|
||||
g_free (url);
|
||||
if (bytes != NULL)
|
||||
{
|
||||
font = font_from_string (context->fontmap, font_name, FALSE);
|
||||
if (!font)
|
||||
{
|
||||
gtk_css_parser_error (parser,
|
||||
GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE,
|
||||
&start_location,
|
||||
gtk_css_parser_get_end_location (parser),
|
||||
"The given url does not define a font named \"%s\"",
|
||||
font_name);
|
||||
}
|
||||
success = add_font_from_bytes (context, bytes, &error);
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
gtk_css_parser_emit_error (parser,
|
||||
&start_location,
|
||||
gtk_css_parser_get_end_location (parser),
|
||||
error);
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
font = font_from_string (context->fontmap, font_name, FALSE);
|
||||
if (!font)
|
||||
{
|
||||
gtk_css_parser_error (parser,
|
||||
GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE,
|
||||
&start_location,
|
||||
gtk_css_parser_get_end_location (parser),
|
||||
"The given url does not define a font named \"%s\"",
|
||||
font_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (context->fontmap)
|
||||
font = font_from_string (context->fontmap, font_name, FALSE);
|
||||
|
||||
if (!font)
|
||||
font = font_from_string (pango_cairo_font_map_get_default (), font_name, TRUE);
|
||||
|
||||
@@ -2255,6 +2244,12 @@ unpack_glyphs (PangoFont *font,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (ascii->glyphs[idx].glyph == PANGO_GLYPH_INVALID_INPUT)
|
||||
{
|
||||
g_clear_pointer (&ascii, pango_glyph_string_free);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gi->glyph = ascii->glyphs[idx].glyph;
|
||||
gi->geometry.width = ascii->glyphs[idx].geometry.width;
|
||||
}
|
||||
@@ -2946,7 +2941,7 @@ typedef struct
|
||||
gsize named_node_counter;
|
||||
GHashTable *named_textures;
|
||||
gsize named_texture_counter;
|
||||
GHashTable *serialized_fonts;
|
||||
GHashTable *fonts;
|
||||
} Printer;
|
||||
|
||||
static void
|
||||
@@ -2961,6 +2956,59 @@ printer_init_check_texture (Printer *printer,
|
||||
g_hash_table_insert (printer->named_textures, texture, g_strdup (""));
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
hb_face_t *face;
|
||||
hb_subset_input_t *input;
|
||||
gboolean serialized;
|
||||
} FontInfo;
|
||||
|
||||
static void
|
||||
font_info_free (gpointer data)
|
||||
{
|
||||
FontInfo *info = (FontInfo *) data;
|
||||
|
||||
hb_face_destroy (info->face);
|
||||
if (info->input)
|
||||
hb_subset_input_destroy (info->input);
|
||||
g_free (info);
|
||||
}
|
||||
|
||||
static void
|
||||
printer_init_collect_font_info (Printer *printer,
|
||||
GskRenderNode *node)
|
||||
{
|
||||
PangoFont *font;
|
||||
FontInfo *info;
|
||||
|
||||
font = gsk_text_node_get_font (node);
|
||||
|
||||
info = (FontInfo *) g_hash_table_lookup (printer->fonts, hb_font_get_face (pango_font_get_hb_font (font)));
|
||||
if (!info)
|
||||
{
|
||||
info = g_new0 (FontInfo, 1);
|
||||
|
||||
info->face = hb_face_reference (hb_font_get_face (pango_font_get_hb_font (font)));
|
||||
if (!g_object_get_data (G_OBJECT (pango_font_get_font_map (font)), "font-files"))
|
||||
{
|
||||
info->input = hb_subset_input_create_or_fail ();
|
||||
hb_subset_input_set_flags (info->input, HB_SUBSET_FLAGS_RETAIN_GIDS);
|
||||
}
|
||||
|
||||
g_hash_table_insert (printer->fonts, info->face, info);
|
||||
}
|
||||
|
||||
if (info->input)
|
||||
{
|
||||
const PangoGlyphInfo *glyphs;
|
||||
guint n_glyphs;
|
||||
|
||||
glyphs = gsk_text_node_get_glyphs (node, &n_glyphs);
|
||||
|
||||
for (guint i = 0; i < n_glyphs; i++)
|
||||
hb_set_add (hb_subset_input_glyph_set (info->input), glyphs[i].glyph);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
printer_init_duplicates_for_node (Printer *printer,
|
||||
GskRenderNode *node)
|
||||
@@ -2976,6 +3024,9 @@ printer_init_duplicates_for_node (Printer *printer,
|
||||
{
|
||||
case GSK_CAIRO_NODE:
|
||||
case GSK_TEXT_NODE:
|
||||
printer_init_collect_font_info (printer, node);
|
||||
break;
|
||||
|
||||
case GSK_COLOR_NODE:
|
||||
case GSK_LINEAR_GRADIENT_NODE:
|
||||
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
|
||||
@@ -3099,7 +3150,7 @@ printer_init (Printer *self,
|
||||
self->named_node_counter = 0;
|
||||
self->named_textures = g_hash_table_new_full (NULL, NULL, NULL, g_free);
|
||||
self->named_texture_counter = 0;
|
||||
self->serialized_fonts = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
self->fonts = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, font_info_free);
|
||||
|
||||
printer_init_duplicates_for_node (self, node);
|
||||
}
|
||||
@@ -3111,7 +3162,7 @@ printer_clear (Printer *self)
|
||||
g_string_free (self->str, TRUE);
|
||||
g_hash_table_unref (self->named_nodes);
|
||||
g_hash_table_unref (self->named_textures);
|
||||
g_hash_table_unref (self->serialized_fonts);
|
||||
g_hash_table_unref (self->fonts);
|
||||
}
|
||||
|
||||
#define IDENT_LEVEL 2 /* Spaces per level */
|
||||
@@ -3232,17 +3283,6 @@ append_rounded_rect (GString *str,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
append_rgba (GString *str,
|
||||
const GdkRGBA *rgba)
|
||||
{
|
||||
char *rgba_str = gdk_rgba_to_string (rgba);
|
||||
|
||||
g_string_append (str, rgba_str);
|
||||
|
||||
g_free (rgba_str);
|
||||
}
|
||||
|
||||
static void
|
||||
append_point (GString *str,
|
||||
const graphene_point_t *p)
|
||||
@@ -3288,7 +3328,7 @@ append_rgba_param (Printer *p,
|
||||
{
|
||||
_indent (p);
|
||||
g_string_append_printf (p->str, "%s: ", param_name);
|
||||
append_rgba (p->str, value);
|
||||
gdk_rgba_print (value, p->str);
|
||||
g_string_append_c (p->str, ';');
|
||||
g_string_append_c (p->str, '\n');
|
||||
}
|
||||
@@ -3442,7 +3482,7 @@ append_stops_param (Printer *p,
|
||||
|
||||
string_append_double (p->str, stops[i].offset);
|
||||
g_string_append_c (p->str, ' ');
|
||||
append_rgba (p->str, &stops[i].color);
|
||||
gdk_rgba_print (&stops[i].color, p->str);
|
||||
}
|
||||
g_string_append (p->str, ";\n");
|
||||
}
|
||||
@@ -3582,14 +3622,46 @@ append_texture_param (Printer *p,
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
|
||||
static void
|
||||
print_font (PangoFont *font)
|
||||
{
|
||||
PangoFontDescription *desc;
|
||||
char *s;
|
||||
hb_face_t *face;
|
||||
hb_blob_t *blob;
|
||||
const char *data;
|
||||
unsigned int length;
|
||||
char *csum;
|
||||
|
||||
desc = pango_font_describe_with_absolute_size (font);
|
||||
s = pango_font_description_to_string (desc);
|
||||
|
||||
face = hb_font_get_face (pango_font_get_hb_font (font));
|
||||
blob = hb_face_reference_blob (face);
|
||||
|
||||
data = hb_blob_get_data (blob, &length);
|
||||
csum = g_compute_checksum_for_data (G_CHECKSUM_SHA256, (const guchar *)data, length);
|
||||
|
||||
g_print ("%s, face %p, sha %s\n", s, face, csum);
|
||||
|
||||
g_free (csum);
|
||||
hb_blob_destroy (blob);
|
||||
g_free (s);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_text_node_serialize_font (GskRenderNode *node,
|
||||
Printer *p)
|
||||
{
|
||||
PangoFont *font = gsk_text_node_get_font (node);
|
||||
PangoFontMap *fontmap = pango_font_get_font_map (font);
|
||||
PangoFontDescription *desc;
|
||||
char *s;
|
||||
FontInfo *info;
|
||||
hb_face_t *face;
|
||||
hb_blob_t *blob;
|
||||
const char *data;
|
||||
guint length;
|
||||
char *b64;
|
||||
|
||||
desc = pango_font_describe_with_absolute_size (font);
|
||||
s = pango_font_description_to_string (desc);
|
||||
@@ -3597,42 +3669,31 @@ gsk_text_node_serialize_font (GskRenderNode *node,
|
||||
g_free (s);
|
||||
pango_font_description_free (desc);
|
||||
|
||||
/* Check if this is a custom font that we created from a url */
|
||||
if (!g_object_get_data (G_OBJECT (fontmap), "font-files"))
|
||||
g_print ("serializing ");
|
||||
print_font (font);
|
||||
info = g_hash_table_lookup (p->fonts, hb_font_get_face (pango_font_get_hb_font (font)));
|
||||
if (info->serialized)
|
||||
return;
|
||||
|
||||
#ifdef HAVE_PANGOFT
|
||||
{
|
||||
FcPattern *pat;
|
||||
FcResult res;
|
||||
const char *file;
|
||||
char *data;
|
||||
gsize len;
|
||||
char *b64;
|
||||
if (info->input)
|
||||
face = hb_subset_or_fail (info->face, info->input);
|
||||
else
|
||||
face = hb_face_reference (info->face);
|
||||
|
||||
pat = pango_fc_font_get_pattern (PANGO_FC_FONT (font));
|
||||
res = FcPatternGetString (pat, FC_FILE, 0, (FcChar8 **)&file);
|
||||
if (res != FcResultMatch)
|
||||
return;
|
||||
blob = hb_face_reference_blob (face);
|
||||
data = hb_blob_get_data (blob, &length);
|
||||
|
||||
if (g_hash_table_contains (p->serialized_fonts, file))
|
||||
return;
|
||||
b64 = base64_encode_with_linebreaks ((const guchar *) data, length);
|
||||
|
||||
if (!g_file_get_contents (file, &data, &len, NULL))
|
||||
return;
|
||||
g_string_append (p->str, " url(\"data:font/ttf;base64,\\\n");
|
||||
append_escaping_newlines (p->str, b64);
|
||||
g_string_append (p->str, "\")");
|
||||
|
||||
g_hash_table_add (p->serialized_fonts, (gpointer) file);
|
||||
g_free (b64);
|
||||
hb_blob_destroy (blob);
|
||||
hb_face_destroy (face);
|
||||
|
||||
b64 = base64_encode_with_linebreaks ((const guchar *) data, len);
|
||||
|
||||
g_string_append (p->str, " url(\"data:font/ttf;base64,\\\n");
|
||||
append_escaping_newlines (p->str, b64);
|
||||
g_string_append (p->str, "\")");
|
||||
|
||||
g_free (b64);
|
||||
g_free (data);
|
||||
}
|
||||
#endif
|
||||
info->serialized = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -4068,7 +4129,7 @@ render_node_print (Printer *p,
|
||||
{
|
||||
if (i > 0)
|
||||
g_string_append_c (p->str, ' ');
|
||||
append_rgba (p->str, &colors[i]);
|
||||
gdk_rgba_print (&colors[i], p->str);
|
||||
}
|
||||
g_string_append (p->str, ";\n");
|
||||
}
|
||||
|
||||
@@ -354,6 +354,8 @@ gsk_stroke_set_miter_limit (GskStroke *self,
|
||||
*
|
||||
* Returns the miter limit of a `GskStroke`.
|
||||
*
|
||||
* Returns: the miter limit
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
float
|
||||
@@ -478,6 +480,8 @@ gsk_stroke_set_dash_offset (GskStroke *self,
|
||||
*
|
||||
* Returns the dash_offset of a `GskStroke`.
|
||||
*
|
||||
* Returns: the dash_offset
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
float
|
||||
|
||||
+1
-1
@@ -2023,7 +2023,7 @@ GskTransformCategory
|
||||
return self->category;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* gsk_transform_new: (constructor):
|
||||
*
|
||||
* Creates a new identity transform.
|
||||
|
||||
@@ -21,12 +21,26 @@
|
||||
|
||||
#include "gtkcsserror.h"
|
||||
|
||||
/**
|
||||
* gtk_css_parser_error_quark:
|
||||
*
|
||||
* Registers an error quark for CSS parsing errors.
|
||||
*
|
||||
* Returns: the error quark
|
||||
**/
|
||||
GQuark
|
||||
gtk_css_parser_error_quark (void)
|
||||
{
|
||||
return g_quark_from_static_string ("gtk-css-parser-error-quark");
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_css_parser_warning_quark:
|
||||
*
|
||||
* Registers an error quark for CSS parsing warnings.
|
||||
*
|
||||
* Returns: the warning quark
|
||||
**/
|
||||
GQuark
|
||||
gtk_css_parser_warning_quark (void)
|
||||
{
|
||||
|
||||
@@ -27,6 +27,11 @@ G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GtkCssLocation GtkCssLocation;
|
||||
|
||||
/**
|
||||
* GtkCssLocation:
|
||||
*
|
||||
* A description of a location inside a CSS stream.
|
||||
*/
|
||||
struct _GtkCssLocation
|
||||
{
|
||||
gsize bytes;
|
||||
|
||||
+31
-4
@@ -26,6 +26,10 @@
|
||||
#include "gtkcsserror.h"
|
||||
#include "gtkcsslocationprivate.h"
|
||||
|
||||
/* We cannot include gtkdebug.h, so we must keep this in sync */
|
||||
extern unsigned int gtk_get_debug_flags (void);
|
||||
#define DEBUG_CHECK_CSS ((gtk_get_debug_flags () & GTK_CSS_PARSER_DEBUG_CSS) != 0)
|
||||
|
||||
static void clear_ref (GtkCssVariableValueReference *ref);
|
||||
|
||||
#define GDK_ARRAY_NAME gtk_css_parser_references
|
||||
@@ -626,7 +630,7 @@ void
|
||||
gtk_css_parser_skip (GtkCssParser *self)
|
||||
{
|
||||
const GtkCssToken *token;
|
||||
|
||||
|
||||
token = gtk_css_parser_get_token (self);
|
||||
if (gtk_css_token_is_preserved (token, NULL))
|
||||
{
|
||||
@@ -659,7 +663,7 @@ gtk_css_parser_skip_until (GtkCssParser *self,
|
||||
GtkCssTokenType token_type)
|
||||
{
|
||||
const GtkCssToken *token;
|
||||
|
||||
|
||||
for (token = gtk_css_parser_get_token (self);
|
||||
!gtk_css_token_is (token, token_type) &&
|
||||
!gtk_css_token_is (token, GTK_CSS_TOKEN_EOF);
|
||||
@@ -812,6 +816,29 @@ gtk_css_parser_warn_syntax (GtkCssParser *self,
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_parser_warn_deprecated (GtkCssParser *self,
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
if (DEBUG_CHECK_CSS)
|
||||
{
|
||||
va_list args;
|
||||
GError *error;
|
||||
|
||||
va_start (args, format);
|
||||
error = g_error_new_valist (GTK_CSS_PARSER_WARNING,
|
||||
GTK_CSS_PARSER_WARNING_DEPRECATED,
|
||||
format, args);
|
||||
gtk_css_parser_emit_error (self,
|
||||
gtk_css_parser_get_start_location (self),
|
||||
gtk_css_parser_get_end_location (self),
|
||||
error);
|
||||
g_error_free (error);
|
||||
va_end (args);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_css_parser_consume_function (GtkCssParser *self,
|
||||
guint min_args,
|
||||
@@ -1133,7 +1160,7 @@ gtk_css_parser_parse_url_arg (GtkCssParser *parser,
|
||||
*out_url = gtk_css_parser_consume_string (parser);
|
||||
if (*out_url == NULL)
|
||||
return 0;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1179,7 +1206,7 @@ gtk_css_parser_consume_url (GtkCssParser *self)
|
||||
gtk_css_parser_error_syntax (self, "Expected a URL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
|
||||
@@ -120,6 +120,9 @@ void gtk_css_parser_warn (GtkCssParser
|
||||
void gtk_css_parser_warn_syntax (GtkCssParser *self,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF(2, 3);
|
||||
void gtk_css_parser_warn_deprecated (GtkCssParser *self,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF(2, 3);
|
||||
|
||||
|
||||
gboolean gtk_css_parser_has_token (GtkCssParser *self,
|
||||
@@ -169,5 +172,9 @@ void gtk_css_parser_get_expanding_variables (GtkCssParser
|
||||
char ***names,
|
||||
gsize *n_variables);
|
||||
|
||||
|
||||
/* We cannot include gtkdebug.h, so we must keep this in sync */
|
||||
#define GTK_CSS_PARSER_DEBUG_CSS (1 << 20)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+27
-1
@@ -53,6 +53,21 @@ gtk_css_section_new (GFile *file,
|
||||
return gtk_css_section_new_with_bytes (file, NULL,start, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_css_section_new_with_bytes: (constructor)
|
||||
* @file: (nullable) (transfer none): The file this section refers to
|
||||
* @bytes: (nullable) (transfer none): The bytes this sections refers to
|
||||
* @start: The start location
|
||||
* @end: The end location
|
||||
*
|
||||
* Creates a new `GtkCssSection` referring to the section
|
||||
* in the given `file` or the given `bytes` from the `start` location to the
|
||||
* `end` location.
|
||||
*
|
||||
* Returns: (transfer full): a new `GtkCssSection`
|
||||
*
|
||||
* Since: 4.16
|
||||
**/
|
||||
GtkCssSection *
|
||||
gtk_css_section_new_with_bytes (GFile *file,
|
||||
GBytes *bytes,
|
||||
@@ -165,6 +180,17 @@ gtk_css_section_get_file (const GtkCssSection *section)
|
||||
return section->file;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_css_section_get_bytes:
|
||||
* @section: the section
|
||||
*
|
||||
* Gets the bytes that @section was parsed from.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the `GBytes` from which the `section`
|
||||
* was parsed
|
||||
*
|
||||
* Since: 4.16
|
||||
**/
|
||||
GBytes *
|
||||
gtk_css_section_get_bytes (const GtkCssSection *section)
|
||||
{
|
||||
@@ -242,7 +268,7 @@ gtk_css_section_print (const GtkCssSection *section,
|
||||
g_string_append (string, "<data>");
|
||||
}
|
||||
|
||||
g_string_append_printf (string, ":%zu:%zu",
|
||||
g_string_append_printf (string, ":%zu:%zu",
|
||||
section->start_location.lines + 1,
|
||||
section->start_location.line_chars + 1);
|
||||
if (section->start_location.lines != section->end_location.lines ||
|
||||
|
||||
@@ -689,6 +689,11 @@ gtk_cell_renderer_progress_class_init (GtkCellRendererProgressClass *klass)
|
||||
PROP_ORIENTATION,
|
||||
"orientation");
|
||||
|
||||
/**
|
||||
* GtkCellRendererProgress:inverted:
|
||||
*
|
||||
* Whether progess is inverted.
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_INVERTED,
|
||||
g_param_spec_boolean ("inverted", NULL, NULL,
|
||||
|
||||
@@ -175,7 +175,8 @@ gtk_cell_renderer_spinner_class_init (GtkCellRendererSpinnerClass *klass)
|
||||
cell_class->get_preferred_height = gtk_cell_renderer_spinner_get_preferred_height;
|
||||
cell_class->snapshot = gtk_cell_renderer_spinner_snapshot;
|
||||
|
||||
/* GtkCellRendererSpinner:active:
|
||||
/**
|
||||
* GtkCellRendererSpinner:active:
|
||||
*
|
||||
* Whether the spinner is active (ie. shown) in the cell
|
||||
*/
|
||||
|
||||
@@ -512,6 +512,8 @@ gtk_combo_box_class_init (GtkComboBoxClass *klass)
|
||||
* This is an [keybinding signal](class.SignalAction.html).
|
||||
*
|
||||
* The default bindings for this signal are Alt+Up and Escape.
|
||||
*
|
||||
* Returns: whether the combo box was popped down
|
||||
*/
|
||||
combo_box_signals[POPDOWN] =
|
||||
g_signal_new_class_handler (I_("popdown"),
|
||||
|
||||
@@ -297,11 +297,21 @@ gtk_entry_completion_class_init (GtkEntryCompletionClass *klass)
|
||||
NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* GtkEntryCompletion:model:
|
||||
*
|
||||
* The model used as data source.
|
||||
*/
|
||||
entry_completion_props[PROP_MODEL] =
|
||||
g_param_spec_object ("model", NULL, NULL,
|
||||
GTK_TYPE_TREE_MODEL,
|
||||
GTK_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* GtkEntryCompletion:minimum-key-length:
|
||||
*
|
||||
* The minimum key length as set for completion.
|
||||
*/
|
||||
entry_completion_props[PROP_MINIMUM_KEY_LENGTH] =
|
||||
g_param_spec_int ("minimum-key-length", NULL, NULL,
|
||||
0, G_MAXINT, 1,
|
||||
|
||||
@@ -410,6 +410,11 @@ gtk_icon_view_class_init (GtkIconViewClass *klass)
|
||||
-1, G_MAXINT, -1,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
||||
|
||||
/**
|
||||
* GtkIconView:model:
|
||||
*
|
||||
* The model of the icon view.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MODEL,
|
||||
g_param_spec_object ("model", NULL, NULL,
|
||||
@@ -516,6 +521,12 @@ gtk_icon_view_class_init (GtkIconViewClass *klass)
|
||||
FALSE,
|
||||
G_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
||||
|
||||
/**
|
||||
* GtkIconView:tooltip-column:
|
||||
*
|
||||
* The column of the icon view model which is being used for displaying
|
||||
* tooltips on it's rows.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_TOOLTIP_COLUMN,
|
||||
g_param_spec_int ("tooltip-column", NULL, NULL,
|
||||
@@ -712,6 +723,8 @@ gtk_icon_view_class_init (GtkIconViewClass *klass)
|
||||
* programmatically.
|
||||
*
|
||||
* The default bindings for this signal are Space, Return and Enter.
|
||||
*
|
||||
* Returns: whether the item was activated
|
||||
*/
|
||||
icon_view_signals[ACTIVATE_CURSOR_ITEM] =
|
||||
g_signal_new (I_("activate-cursor-item"),
|
||||
@@ -747,6 +760,8 @@ gtk_icon_view_class_init (GtkIconViewClass *klass)
|
||||
* - PageUp/PageDown which move by "pages"
|
||||
* All of these will extend the selection when combined with
|
||||
* the Shift modifier.
|
||||
*
|
||||
* Returns: whether the cursor was moved
|
||||
*/
|
||||
icon_view_signals[MOVE_CURSOR] =
|
||||
g_signal_new (I_("move-cursor"),
|
||||
|
||||
@@ -62,7 +62,7 @@ struct _GtkMessageDialog
|
||||
*
|
||||
* > Please note that %GTK_BUTTONS_OK, %GTK_BUTTONS_YES_NO
|
||||
* > and %GTK_BUTTONS_OK_CANCEL are discouraged by the
|
||||
* > [GNOME Human Interface Guidelines](http://library.gnome.org/devel/hig-book/stable/).
|
||||
* > [GNOME Human Interface Guidelines](https://developer.gnome.org/hig/).
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
|
||||
@@ -99,7 +99,6 @@ window_handle_exported (GtkWindow *window,
|
||||
* a given uri.
|
||||
*
|
||||
* The @callback will be called when the launch is completed.
|
||||
* It should call gtk_show_uri_full_finish() to obtain the result.
|
||||
*
|
||||
* This is the recommended call to be used as it passes information
|
||||
* necessary for sandbox helpers to parent their dialogs properly.
|
||||
@@ -153,8 +152,8 @@ gtk_show_uri_full (GtkWindow *parent,
|
||||
* Returns: %TRUE if the URI was shown successfully.
|
||||
* Otherwise, %FALSE is returned and @error is set
|
||||
*
|
||||
* Deprecated: 4.10: Use [method@Gtk.FileLauncher.launch_finish] or
|
||||
* [method@Gtk.UriLauncher.launch_finish] instead
|
||||
* Deprecated: 4.10: Use [method@Gtk.FileLauncher.launch] or
|
||||
* [method@Gtk.UriLauncher.launch] instead
|
||||
*/
|
||||
gboolean
|
||||
gtk_show_uri_full_finish (GtkWindow *parent,
|
||||
|
||||
@@ -122,6 +122,11 @@ gtk_style_context_class_init (GtkStyleContextClass *klass)
|
||||
object_class->set_property = gtk_style_context_impl_set_property;
|
||||
object_class->get_property = gtk_style_context_impl_get_property;
|
||||
|
||||
/**
|
||||
* GtkStyleContext:display:
|
||||
*
|
||||
* The display of the style context.
|
||||
*/
|
||||
properties[PROP_DISPLAY] =
|
||||
g_param_spec_object ("display", NULL, NULL,
|
||||
GDK_TYPE_DISPLAY,
|
||||
@@ -773,13 +778,20 @@ gtk_style_context_resolve_color (GtkStyleContext *context,
|
||||
{
|
||||
GtkStyleContextPrivate *priv = gtk_style_context_get_instance_private (context);
|
||||
GtkCssValue *val;
|
||||
GtkCssComputeContext ctx = { NULL, };
|
||||
|
||||
g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), FALSE);
|
||||
g_return_val_if_fail (color != NULL, FALSE);
|
||||
g_return_val_if_fail (result != NULL, FALSE);
|
||||
|
||||
ctx.provider = GTK_STYLE_PROVIDER (priv->cascade);
|
||||
ctx.style = gtk_css_node_get_style (priv->cssnode);
|
||||
if (gtk_css_node_get_parent (priv->cssnode))
|
||||
ctx.parent_style = gtk_css_node_get_style (gtk_css_node_get_parent (priv->cssnode));
|
||||
|
||||
val = gtk_css_color_value_resolve (color,
|
||||
GTK_STYLE_PROVIDER (priv->cascade),
|
||||
GTK_CSS_PROPERTY_COLOR,
|
||||
&ctx,
|
||||
_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_COLOR));
|
||||
|
||||
if (val == NULL)
|
||||
|
||||
@@ -527,12 +527,22 @@ gtk_tree_model_filter_class_init (GtkTreeModelFilterClass *filter_class)
|
||||
filter_class->visible = gtk_tree_model_filter_real_visible;
|
||||
filter_class->modify = gtk_tree_model_filter_real_modify;
|
||||
|
||||
/**
|
||||
* GtkTreeModelFilter:child-model:
|
||||
*
|
||||
* The child model of the tree model filter.
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_CHILD_MODEL,
|
||||
g_param_spec_object ("child-model", NULL, NULL,
|
||||
GTK_TYPE_TREE_MODEL,
|
||||
GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
/**
|
||||
* GtkTreeModelFilter:virtual-root:
|
||||
*
|
||||
* The virtual root of the tree model filter.
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_VIRTUAL_ROOT,
|
||||
g_param_spec_boxed ("virtual-root", NULL, NULL,
|
||||
|
||||
@@ -479,6 +479,12 @@ gtk_tree_model_sort_class_init (GtkTreeModelSortClass *class)
|
||||
object_class->finalize = gtk_tree_model_sort_finalize;
|
||||
|
||||
/* Properties */
|
||||
|
||||
/**
|
||||
* GtkTreeModelSort:model:
|
||||
*
|
||||
* The model of the tree model sort.
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_MODEL,
|
||||
g_param_spec_object ("model", NULL, NULL,
|
||||
|
||||
@@ -1129,7 +1129,7 @@ gtk_about_dialog_set_copyright (GtkAboutDialog *about,
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_about_dialog_get_comments: (attributes org.gtk.Method.set_property=comments)
|
||||
* gtk_about_dialog_get_comments: (attributes org.gtk.Method.get_property=comments)
|
||||
* @about: a `GtkAboutDialog`
|
||||
*
|
||||
* Returns the comments string.
|
||||
|
||||
@@ -505,6 +505,8 @@ out:
|
||||
*
|
||||
* If the parse operation fails, @accelerator_key and @accelerator_mods will
|
||||
* be set to 0 (zero).
|
||||
*
|
||||
* Returns: whether parsing succeeded
|
||||
*/
|
||||
gboolean
|
||||
gtk_accelerator_parse (const char *accelerator,
|
||||
|
||||
@@ -56,10 +56,21 @@ G_DEFINE_INTERFACE (GtkActionable, gtk_actionable, GTK_TYPE_WIDGET)
|
||||
static void
|
||||
gtk_actionable_default_init (GtkActionableInterface *iface)
|
||||
{
|
||||
|
||||
/**
|
||||
* GtkActionable:action-name:
|
||||
*
|
||||
* The name of the action with which this widget should be associated.
|
||||
*/
|
||||
g_object_interface_install_property (iface,
|
||||
g_param_spec_string ("action-name", NULL, NULL,
|
||||
NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* GtkActionable:action-target:
|
||||
*
|
||||
* The target value of the actionable widget's action.
|
||||
*/
|
||||
g_object_interface_install_property (iface,
|
||||
g_param_spec_variant ("action-target", NULL, NULL,
|
||||
G_VARIANT_TYPE_ANY, NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
@@ -33,8 +33,7 @@
|
||||
* are needed to present a message to the user.
|
||||
*
|
||||
* The message is shown with the [method@Gtk.AlertDialog.choose]
|
||||
* function. This API follows the GIO async pattern, and the result can
|
||||
* be obtained by calling [method@Gtk.AlertDialog.choose_finish].
|
||||
* function.
|
||||
*
|
||||
* If you don't need to wait for a button to be clicked, you can use
|
||||
* [method@Gtk.AlertDialog.show].
|
||||
@@ -687,10 +686,6 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
*
|
||||
* This function shows the alert to the user.
|
||||
*
|
||||
* The @callback will be called when the alert is dismissed.
|
||||
* It should call [method@Gtk.AlertDialog.choose_finish]
|
||||
* to obtain the result.
|
||||
*
|
||||
* It is ok to pass `NULL` for the callback if the alert
|
||||
* does not have more than one button. A simpler API for
|
||||
* this case is [method@Gtk.AlertDialog.show].
|
||||
|
||||
@@ -2953,6 +2953,13 @@ gtk_builder_get_type_from_name (GtkBuilder *builder,
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_builder_error_quark:
|
||||
*
|
||||
* Registers an error quark for [class@Gtk.Builder] errors.
|
||||
*
|
||||
* Returns: the error quark
|
||||
**/
|
||||
GQuark
|
||||
gtk_builder_error_quark (void)
|
||||
{
|
||||
|
||||
@@ -434,11 +434,10 @@ gtk_builder_cscope_new (void)
|
||||
|
||||
/**
|
||||
* gtk_builder_cscope_add_callback:
|
||||
* @self: a `GtkBuilderCScope`
|
||||
* @callback_symbols: (scope async): The callback pointer
|
||||
* @scope: a `GtkBuilderCScope`
|
||||
* @callback: (scope async): The callback pointer
|
||||
*
|
||||
* Adds the @callback_symbol to the scope of @builder under its
|
||||
* own name.
|
||||
* Adds the @callback to the scope of @builder under its own name.
|
||||
*
|
||||
* This is a convenience wrapper of [method@Gtk.BuilderCScope.add_callback_symbol].
|
||||
*
|
||||
|
||||
@@ -232,6 +232,14 @@ gtk_color_chooser_dialog_class_init (GtkColorChooserDialogClass *class)
|
||||
|
||||
g_object_class_override_property (object_class, PROP_RGBA, "rgba");
|
||||
g_object_class_override_property (object_class, PROP_USE_ALPHA, "use-alpha");
|
||||
|
||||
/**
|
||||
* GtkColorChooserDialog:show-editor:
|
||||
*
|
||||
* Whether the color chooser dialog is showing the single-color editor.
|
||||
*
|
||||
* It can be set to switch the color chooser into single-color editing mode.
|
||||
*/
|
||||
g_object_class_install_property (object_class, PROP_SHOW_EDITOR,
|
||||
g_param_spec_boolean ("show-editor", NULL, NULL,
|
||||
FALSE, GTK_PARAM_READWRITE));
|
||||
|
||||
@@ -36,9 +36,7 @@
|
||||
* should be modal.
|
||||
*
|
||||
* The dialog is shown with the [method@Gtk.ColorDialog.choose_rgba]
|
||||
* function. This API follows the GIO async pattern, and the
|
||||
* result can be obtained by calling
|
||||
* [method@Gtk.ColorDialog.choose_rgba_finish].
|
||||
* function.
|
||||
*
|
||||
* See [class@Gtk.ColorDialogButton] for a convenient control
|
||||
* that uses `GtkColorDialog` and presents the results.
|
||||
@@ -436,10 +434,6 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
* This function initiates a color choice operation by
|
||||
* presenting a color chooser dialog to the user.
|
||||
*
|
||||
* The @callback will be called when the dialog is dismissed.
|
||||
* It should call [method@Gtk.ColorDialog.choose_rgba_finish]
|
||||
* to obtain the result.
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
void
|
||||
|
||||
+198
-1
@@ -32,7 +32,9 @@
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gtkcolorutils.h"
|
||||
#include "gtkcolorutilsprivate.h"
|
||||
#include "gdkhslaprivate.h"
|
||||
#include <math.h>
|
||||
|
||||
/* Converts from RGB to HSV */
|
||||
static void
|
||||
@@ -226,3 +228,198 @@ gtk_rgb_to_hsv (float r, float g, float b,
|
||||
if (v)
|
||||
*v = b;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_rgb_to_hsl (float red, float green, float blue,
|
||||
float *hue, float *saturation, float *lightness)
|
||||
{
|
||||
GdkHSLA hsla;
|
||||
|
||||
_gdk_hsla_init_from_rgba (&hsla, &(GdkRGBA) { red, green, blue, 1.0 });
|
||||
|
||||
*hue = hsla.hue;
|
||||
*saturation = hsla.saturation;
|
||||
*lightness = hsla.lightness;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_hsl_to_rgb (float hue, float saturation, float lightness,
|
||||
float *red, float *green, float *blue)
|
||||
{
|
||||
GdkRGBA rgba;
|
||||
|
||||
_gdk_rgba_init_from_hsla (&rgba, &(GdkHSLA) { hue, saturation, lightness, 1.0 });
|
||||
|
||||
*red = rgba.red;
|
||||
*green = rgba.green;
|
||||
*blue = rgba.blue;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_rgb_to_hwb (float red, float green, float blue,
|
||||
float *hue, float *white, float *black)
|
||||
{
|
||||
GdkRGBA rgba = (GdkRGBA) { red, green, blue, 1 };
|
||||
GdkHSLA hsla;
|
||||
|
||||
_gdk_hsla_init_from_rgba (&hsla, &rgba);
|
||||
|
||||
*hue = hsla.hue;
|
||||
*white = MIN (MIN (red, green), blue);
|
||||
*black = (1 - MAX (MAX (red, green), blue));
|
||||
}
|
||||
|
||||
void
|
||||
gtk_hwb_to_rgb (float hue, float white, float black,
|
||||
float *red, float *green, float *blue)
|
||||
{
|
||||
GdkHSLA hsla;
|
||||
GdkRGBA rgba;
|
||||
|
||||
if (white + black >= 1)
|
||||
{
|
||||
float gray = white / (white + black);
|
||||
|
||||
*red = gray;
|
||||
*green = gray;
|
||||
*blue = gray;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
hsla.hue = hue;
|
||||
hsla.saturation = 1.0;
|
||||
hsla.lightness = 0.5;
|
||||
|
||||
_gdk_rgba_init_from_hsla (&rgba, &hsla);
|
||||
|
||||
*red = rgba.red * (1 - white - black) + white;
|
||||
*green = rgba.green * (1 - white - black) + white;
|
||||
*blue = rgba.blue * (1 - white - black) + white;
|
||||
}
|
||||
|
||||
#define DEG_TO_RAD(x) ((x) * G_PI / 180)
|
||||
#define RAD_TO_DEG(x) ((x) * 180 / G_PI)
|
||||
|
||||
static inline void
|
||||
_sincosf (float angle,
|
||||
float *out_s,
|
||||
float *out_c)
|
||||
{
|
||||
#ifdef HAVE_SINCOSF
|
||||
sincosf (angle, out_s, out_c);
|
||||
#else
|
||||
*out_s = sinf (angle);
|
||||
*out_c = cosf (angle);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
gtk_oklab_to_oklch (float L, float a, float b,
|
||||
float *L2, float *C, float *H)
|
||||
{
|
||||
*L2 = L;
|
||||
*C = hypotf (a, b);
|
||||
*H = RAD_TO_DEG (atan2 (b, a));
|
||||
*H = fmod (*H, 360);
|
||||
if (*H < 0)
|
||||
*H += 360;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_oklch_to_oklab (float L, float C, float H,
|
||||
float *L2, float *a, float *b)
|
||||
{
|
||||
*L2 = L;
|
||||
_sincosf (DEG_TO_RAD (H), b, a);
|
||||
*a *= C;
|
||||
*b *= C;
|
||||
}
|
||||
|
||||
static float
|
||||
apply_gamma (float v)
|
||||
{
|
||||
if (v > 0.0031308)
|
||||
return 1.055 * pow (v, 1/2.4) - 0.055;
|
||||
else
|
||||
return 12.92 * v;
|
||||
}
|
||||
|
||||
static float
|
||||
unapply_gamma (float v)
|
||||
{
|
||||
if (v >= 0.04045)
|
||||
return pow (((v + 0.055)/(1 + 0.055)), 2.4);
|
||||
else
|
||||
return v / 12.92;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_oklab_to_linear_srgb (float L, float a, float b,
|
||||
float *red, float *green, float *blue)
|
||||
{
|
||||
float l = L + 0.3963377774f * a + 0.2158037573f * b;
|
||||
float m = L - 0.1055613458f * a - 0.0638541728f * b;
|
||||
float s = L - 0.0894841775f * a - 1.2914855480f * b;
|
||||
|
||||
l = powf (l, 3);
|
||||
m = powf (m, 3);
|
||||
s = powf (s, 3);
|
||||
|
||||
*red = +4.0767416621f * l - 3.3077115913f * m + 0.2309699292f * s;
|
||||
*green = -1.2684380046f * l + 2.6097574011f * m - 0.3413193965f * s;
|
||||
*blue = -0.0041960863f * l - 0.7034186147f * m + 1.7076147010f * s;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_oklab_to_rgb (float L, float a, float b,
|
||||
float *red, float *green, float *blue)
|
||||
{
|
||||
float linear_red, linear_green, linear_blue;
|
||||
gtk_oklab_to_linear_srgb (L, a, b, &linear_red, &linear_green, &linear_blue);
|
||||
gtk_linear_srgb_to_rgb (linear_red, linear_green, linear_blue, red, green, blue);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_linear_srgb_to_oklab (float red, float green, float blue,
|
||||
float *L, float *a, float *b)
|
||||
{
|
||||
float l = 0.4122214708f * red + 0.5363325363f * green + 0.0514459929f * blue;
|
||||
float m = 0.2119034982f * red + 0.6806995451f * green + 0.1073969566f * blue;
|
||||
float s = 0.0883024619f * red + 0.2817188376f * green + 0.6299787005f * blue;
|
||||
|
||||
l = cbrtf (l);
|
||||
m = cbrtf (m);
|
||||
s = cbrtf (s);
|
||||
|
||||
*L = 0.2104542553f*l + 0.7936177850f*m - 0.0040720468f*s;
|
||||
*a = 1.9779984951f*l - 2.4285922050f*m + 0.4505937099f*s;
|
||||
*b = 0.0259040371f*l + 0.7827717662f*m - 0.8086757660f*s;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_rgb_to_oklab (float red, float green, float blue,
|
||||
float *L, float *a, float *b)
|
||||
{
|
||||
float linear_red, linear_green, linear_blue;
|
||||
gtk_rgb_to_linear_srgb (red, green, blue, &linear_red, &linear_green, &linear_blue);
|
||||
gtk_linear_srgb_to_oklab (linear_red, linear_green, linear_blue, L, a, b);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_rgb_to_linear_srgb (float red, float green, float blue,
|
||||
float *linear_red, float *linear_green, float *linear_blue)
|
||||
{
|
||||
*linear_red = unapply_gamma (red);
|
||||
*linear_green = unapply_gamma (green);
|
||||
*linear_blue = unapply_gamma (blue);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_linear_srgb_to_rgb (float linear_red, float linear_green, float linear_blue,
|
||||
float *red, float *green, float *blue)
|
||||
{
|
||||
*red = apply_gamma (linear_red);
|
||||
*green = apply_gamma (linear_green);
|
||||
*blue = apply_gamma (linear_blue);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2024 Red Hat, Inc.
|
||||
*
|
||||
* 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 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gtkcolorutils.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void gtk_rgb_to_hsl (float red, float green, float blue,
|
||||
float *hue, float *saturation, float *lightness);
|
||||
void gtk_hsl_to_rgb (float hue, float saturation, float lightness,
|
||||
float *red, float *green, float *blue);
|
||||
|
||||
void gtk_rgb_to_hwb (float red, float green, float blue,
|
||||
float *hue, float *white, float *black);
|
||||
void gtk_hwb_to_rgb (float hue, float white, float black,
|
||||
float *red, float *green, float *blue);
|
||||
|
||||
void gtk_oklab_to_oklch (float L, float a, float b,
|
||||
float *L2, float *C, float *H);
|
||||
void gtk_oklch_to_oklab (float L, float C, float H,
|
||||
float *L2, float *a, float *b);
|
||||
|
||||
void gtk_oklab_to_linear_srgb (float L, float a, float b,
|
||||
float *red, float *green, float *blue);
|
||||
void gtk_linear_srgb_to_oklab (float red, float green, float blue,
|
||||
float *L, float *a, float *b);
|
||||
|
||||
void gtk_oklab_to_rgb (float L, float a, float b,
|
||||
float *red, float *green, float *blue);
|
||||
void gtk_rgb_to_oklab (float red, float green, float blue,
|
||||
float *L, float *a, float *b);
|
||||
|
||||
void gtk_rgb_to_linear_srgb (float red, float green, float blue,
|
||||
float *linear_red, float *linear_green, float *linear_blue);
|
||||
void gtk_linear_srgb_to_rgb (float linear_red, float linear_green, float linear_blue,
|
||||
float *red, float *green, float *blue);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1924,6 +1924,13 @@ attribute_from_name (const char *name)
|
||||
return GTK_CONSTRAINT_ATTRIBUTE_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_vfl_parser_error_quark:
|
||||
*
|
||||
* Registers an error quark for VFL error parsing.
|
||||
*
|
||||
* Returns: the error quark
|
||||
**/
|
||||
GQuark
|
||||
gtk_constraint_vfl_parser_error_quark (void)
|
||||
{
|
||||
|
||||
@@ -645,15 +645,20 @@ gtk_css_animated_style_get_intrinsic_value (GtkCssAnimatedStyle *style,
|
||||
return gtk_css_style_get_value (style->style, id);
|
||||
}
|
||||
|
||||
void
|
||||
gboolean
|
||||
gtk_css_animated_style_set_animated_custom_value (GtkCssAnimatedStyle *animated,
|
||||
int id,
|
||||
GtkCssVariableValue *value)
|
||||
{
|
||||
GtkCssStyle *style = (GtkCssStyle *)animated;
|
||||
GtkCssVariableValue *old_value;
|
||||
|
||||
gtk_internal_return_if_fail (GTK_IS_CSS_ANIMATED_STYLE (style));
|
||||
gtk_internal_return_if_fail (value != NULL);
|
||||
gtk_internal_return_val_if_fail (GTK_IS_CSS_ANIMATED_STYLE (style), FALSE);
|
||||
gtk_internal_return_val_if_fail (value != NULL, FALSE);
|
||||
|
||||
old_value = gtk_css_style_get_custom_property (style, id);
|
||||
if (gtk_css_variable_value_equal (old_value, value))
|
||||
return FALSE;
|
||||
|
||||
if (style->variables == NULL)
|
||||
{
|
||||
@@ -669,6 +674,8 @@ gtk_css_animated_style_set_animated_custom_value (GtkCssAnimatedStyle *animated,
|
||||
}
|
||||
|
||||
gtk_css_variable_set_add (style->variables, id, value);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -70,7 +70,7 @@ void gtk_css_animated_style_set_animated_value(GtkCssAnimated
|
||||
GtkCssValue * gtk_css_animated_style_get_intrinsic_value (GtkCssAnimatedStyle *style,
|
||||
guint id);
|
||||
|
||||
void gtk_css_animated_style_set_animated_custom_value (GtkCssAnimatedStyle *animated,
|
||||
gboolean gtk_css_animated_style_set_animated_custom_value (GtkCssAnimatedStyle *animated,
|
||||
int id,
|
||||
GtkCssVariableValue *value);
|
||||
|
||||
|
||||
@@ -126,11 +126,10 @@ gtk_css_animation_apply_values (GtkStyleAnimation *style_animation,
|
||||
if (!value)
|
||||
continue;
|
||||
|
||||
gtk_css_animated_style_set_animated_custom_value (style, variable_id, value);
|
||||
if (gtk_css_animated_style_set_animated_custom_value (style, variable_id, value))
|
||||
change |= GTK_CSS_ANIMATION_CHANGE_VARIABLES;
|
||||
|
||||
gtk_css_variable_value_unref (value);
|
||||
|
||||
change |= GTK_CSS_ANIMATION_CHANGE_VARIABLES;
|
||||
}
|
||||
|
||||
for (i = 0; i < _gtk_css_keyframes_get_n_properties (resolved_keyframes); i++)
|
||||
|
||||
+60
-42
@@ -21,12 +21,14 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
GtkCssValue * gtk_css_calc_value_parse_sum (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags);
|
||||
GtkCssValue * gtk_css_calc_value_parse_sum (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags,
|
||||
GtkCssNumberParseContext *ctx);
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_calc_value_parse_value (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags)
|
||||
gtk_css_calc_value_parse_value (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags,
|
||||
GtkCssNumberParseContext *ctx)
|
||||
{
|
||||
if (gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_OPEN_PARENS))
|
||||
{
|
||||
@@ -34,7 +36,7 @@ gtk_css_calc_value_parse_value (GtkCssParser *parser,
|
||||
|
||||
gtk_css_parser_start_block (parser);
|
||||
|
||||
result = gtk_css_calc_value_parse_sum (parser, flags);
|
||||
result = gtk_css_calc_value_parse_sum (parser, flags, ctx);
|
||||
if (result == NULL)
|
||||
{
|
||||
gtk_css_parser_end_block (parser);
|
||||
@@ -60,7 +62,7 @@ gtk_css_calc_value_parse_value (GtkCssParser *parser,
|
||||
return result;
|
||||
}
|
||||
|
||||
return gtk_css_number_value_parse (parser, flags);
|
||||
return gtk_css_number_value_parse_with_context (parser, flags, ctx);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -71,8 +73,9 @@ is_number (GtkCssValue *value)
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_calc_value_parse_product (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags)
|
||||
gtk_css_calc_value_parse_product (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags,
|
||||
GtkCssNumberParseContext *ctx)
|
||||
{
|
||||
GtkCssValue *result, *value, *temp;
|
||||
GtkCssNumberParseFlags actual_flags;
|
||||
@@ -81,7 +84,7 @@ gtk_css_calc_value_parse_product (GtkCssParser *parser,
|
||||
actual_flags = flags | GTK_CSS_PARSE_NUMBER;
|
||||
gtk_css_parser_get_token (parser);
|
||||
start = *gtk_css_parser_get_start_location (parser);
|
||||
result = gtk_css_calc_value_parse_value (parser, actual_flags);
|
||||
result = gtk_css_calc_value_parse_value (parser, actual_flags, ctx);
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -92,7 +95,7 @@ gtk_css_calc_value_parse_product (GtkCssParser *parser,
|
||||
|
||||
if (gtk_css_parser_try_delim (parser, '*'))
|
||||
{
|
||||
value = gtk_css_calc_value_parse_product (parser, actual_flags);
|
||||
value = gtk_css_calc_value_parse_product (parser, actual_flags, ctx);
|
||||
if (value == NULL)
|
||||
goto fail;
|
||||
if (is_number (value))
|
||||
@@ -105,7 +108,7 @@ gtk_css_calc_value_parse_product (GtkCssParser *parser,
|
||||
}
|
||||
else if (gtk_css_parser_try_delim (parser, '/'))
|
||||
{
|
||||
value = gtk_css_calc_value_parse_product (parser, GTK_CSS_PARSE_NUMBER);
|
||||
value = gtk_css_calc_value_parse_product (parser, GTK_CSS_PARSE_NUMBER, ctx);
|
||||
if (value == NULL)
|
||||
goto fail;
|
||||
temp = gtk_css_number_value_multiply (result, 1.0 / gtk_css_number_value_get (value, 100));
|
||||
@@ -137,12 +140,13 @@ fail:
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
gtk_css_calc_value_parse_sum (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags)
|
||||
gtk_css_calc_value_parse_sum (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags,
|
||||
GtkCssNumberParseContext *ctx)
|
||||
{
|
||||
GtkCssValue *result;
|
||||
|
||||
result = gtk_css_calc_value_parse_product (parser, flags);
|
||||
result = gtk_css_calc_value_parse_product (parser, flags, ctx);
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -152,13 +156,13 @@ gtk_css_calc_value_parse_sum (GtkCssParser *parser,
|
||||
|
||||
if (gtk_css_parser_try_delim (parser, '+'))
|
||||
{
|
||||
next = gtk_css_calc_value_parse_product (parser, flags);
|
||||
next = gtk_css_calc_value_parse_product (parser, flags, ctx);
|
||||
if (next == NULL)
|
||||
goto fail;
|
||||
}
|
||||
else if (gtk_css_parser_try_delim (parser, '-'))
|
||||
{
|
||||
temp = gtk_css_calc_value_parse_product (parser, flags);
|
||||
temp = gtk_css_calc_value_parse_product (parser, flags, ctx);
|
||||
if (temp == NULL)
|
||||
goto fail;
|
||||
next = gtk_css_number_value_multiply (temp, -1);
|
||||
@@ -193,6 +197,7 @@ fail:
|
||||
typedef struct
|
||||
{
|
||||
GtkCssNumberParseFlags flags;
|
||||
GtkCssNumberParseContext *ctx;
|
||||
GtkCssValue *value;
|
||||
} ParseCalcData;
|
||||
|
||||
@@ -203,7 +208,7 @@ gtk_css_calc_value_parse_arg (GtkCssParser *parser,
|
||||
{
|
||||
ParseCalcData *data = data_;
|
||||
|
||||
data->value = gtk_css_calc_value_parse_sum (parser, data->flags);
|
||||
data->value = gtk_css_calc_value_parse_sum (parser, data->flags, data->ctx);
|
||||
if (data->value == NULL)
|
||||
return 0;
|
||||
|
||||
@@ -211,14 +216,16 @@ gtk_css_calc_value_parse_arg (GtkCssParser *parser,
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
gtk_css_calc_value_parse (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags)
|
||||
gtk_css_calc_value_parse (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags,
|
||||
GtkCssNumberParseContext *ctx)
|
||||
{
|
||||
ParseCalcData data;
|
||||
|
||||
/* This can only be handled at compute time, we allow '-' after all */
|
||||
data.flags = flags & ~GTK_CSS_POSITIVE_ONLY;
|
||||
data.value = NULL;
|
||||
data.ctx = ctx;
|
||||
|
||||
if (!gtk_css_parser_has_function (parser, "calc"))
|
||||
{
|
||||
@@ -235,6 +242,7 @@ gtk_css_calc_value_parse (GtkCssParser *parser,
|
||||
typedef struct
|
||||
{
|
||||
GtkCssNumberParseFlags flags;
|
||||
GtkCssNumberParseContext *ctx;
|
||||
GPtrArray *values;
|
||||
} ParseArgnData;
|
||||
|
||||
@@ -246,7 +254,7 @@ gtk_css_argn_value_parse_arg (GtkCssParser *parser,
|
||||
ParseArgnData *data = data_;
|
||||
GtkCssValue *value;
|
||||
|
||||
value = gtk_css_calc_value_parse_sum (parser, data->flags);
|
||||
value = gtk_css_calc_value_parse_sum (parser, data->flags, data->ctx);
|
||||
if (value == NULL)
|
||||
return 0;
|
||||
|
||||
@@ -258,6 +266,7 @@ gtk_css_argn_value_parse_arg (GtkCssParser *parser,
|
||||
typedef struct
|
||||
{
|
||||
GtkCssNumberParseFlags flags;
|
||||
GtkCssNumberParseContext *ctx;
|
||||
GtkCssValue *values[3];
|
||||
} ParseClampData;
|
||||
|
||||
@@ -277,7 +286,7 @@ gtk_css_clamp_value_parse_arg (GtkCssParser *parser,
|
||||
}
|
||||
}
|
||||
|
||||
data->values[arg] = gtk_css_calc_value_parse_sum (parser, data->flags);
|
||||
data->values[arg] = gtk_css_calc_value_parse_sum (parser, data->flags, data->ctx);
|
||||
if (data->values[arg] == NULL)
|
||||
return 0;
|
||||
|
||||
@@ -285,9 +294,10 @@ gtk_css_clamp_value_parse_arg (GtkCssParser *parser,
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
gtk_css_clamp_value_parse (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags,
|
||||
guint type)
|
||||
gtk_css_clamp_value_parse (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags,
|
||||
GtkCssNumberParseContext *ctx,
|
||||
guint type)
|
||||
{
|
||||
ParseClampData data;
|
||||
GtkCssValue *result = NULL;
|
||||
@@ -300,6 +310,7 @@ gtk_css_clamp_value_parse (GtkCssParser *parser,
|
||||
|
||||
/* This can only be handled at compute time, we allow '-' after all */
|
||||
data.flags = flags & ~GTK_CSS_POSITIVE_ONLY;
|
||||
data.ctx = ctx;
|
||||
data.values[0] = NULL;
|
||||
data.values[1] = NULL;
|
||||
data.values[2] = NULL;
|
||||
@@ -326,6 +337,7 @@ gtk_css_clamp_value_parse (GtkCssParser *parser,
|
||||
|
||||
typedef struct {
|
||||
GtkCssNumberParseFlags flags;
|
||||
GtkCssNumberParseContext *ctx;
|
||||
guint mode;
|
||||
gboolean has_mode;
|
||||
GtkCssValue *values[2];
|
||||
@@ -352,13 +364,13 @@ gtk_css_round_value_parse_arg (GtkCssParser *parser,
|
||||
}
|
||||
}
|
||||
|
||||
data->values[0] = gtk_css_calc_value_parse_sum (parser, data->flags);
|
||||
data->values[0] = gtk_css_calc_value_parse_sum (parser, data->flags, data->ctx);
|
||||
if (data->values[0] == NULL)
|
||||
return 0;
|
||||
}
|
||||
else if (arg == 1)
|
||||
{
|
||||
GtkCssValue *value = gtk_css_calc_value_parse_sum (parser, data->flags);
|
||||
GtkCssValue *value = gtk_css_calc_value_parse_sum (parser, data->flags, data->ctx);
|
||||
|
||||
if (value == NULL)
|
||||
return 0;
|
||||
@@ -376,7 +388,7 @@ gtk_css_round_value_parse_arg (GtkCssParser *parser,
|
||||
return 0;
|
||||
}
|
||||
|
||||
data->values[1] = gtk_css_calc_value_parse_sum (parser, data->flags);
|
||||
data->values[1] = gtk_css_calc_value_parse_sum (parser, data->flags, data->ctx);
|
||||
|
||||
if (data->values[1] == NULL)
|
||||
return 0;
|
||||
@@ -386,9 +398,10 @@ gtk_css_round_value_parse_arg (GtkCssParser *parser,
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
gtk_css_round_value_parse (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags,
|
||||
guint type)
|
||||
gtk_css_round_value_parse (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags,
|
||||
GtkCssNumberParseContext *ctx,
|
||||
guint type)
|
||||
{
|
||||
ParseRoundData data;
|
||||
GtkCssValue *result = NULL;
|
||||
@@ -400,6 +413,7 @@ gtk_css_round_value_parse (GtkCssParser *parser,
|
||||
}
|
||||
|
||||
data.flags = flags & ~GTK_CSS_POSITIVE_ONLY;
|
||||
data.ctx = ctx;
|
||||
data.mode = ROUND_NEAREST;
|
||||
data.has_mode = FALSE;
|
||||
data.values[0] = NULL;
|
||||
@@ -430,6 +444,7 @@ gtk_css_round_value_parse (GtkCssParser *parser,
|
||||
|
||||
typedef struct {
|
||||
GtkCssNumberParseFlags flags;
|
||||
GtkCssNumberParseContext *ctx;
|
||||
GtkCssValue *values[2];
|
||||
} ParseArg2Data;
|
||||
|
||||
@@ -440,7 +455,7 @@ gtk_css_arg2_value_parse_arg (GtkCssParser *parser,
|
||||
{
|
||||
ParseArg2Data *data = data_;
|
||||
|
||||
data->values[arg] = gtk_css_calc_value_parse_sum (parser, data->flags);
|
||||
data->values[arg] = gtk_css_calc_value_parse_sum (parser, data->flags, data->ctx);
|
||||
if (data->values[arg] == NULL)
|
||||
return 0;
|
||||
|
||||
@@ -448,12 +463,13 @@ gtk_css_arg2_value_parse_arg (GtkCssParser *parser,
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
gtk_css_arg2_value_parse (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags,
|
||||
guint min_args,
|
||||
guint max_args,
|
||||
const char *function,
|
||||
guint type)
|
||||
gtk_css_arg2_value_parse (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags,
|
||||
GtkCssNumberParseContext *ctx,
|
||||
guint min_args,
|
||||
guint max_args,
|
||||
const char *function,
|
||||
guint type)
|
||||
{
|
||||
ParseArg2Data data;
|
||||
GtkCssValue *result = NULL;
|
||||
@@ -467,6 +483,7 @@ gtk_css_arg2_value_parse (GtkCssParser *parser,
|
||||
}
|
||||
|
||||
data.flags = flags & ~GTK_CSS_POSITIVE_ONLY;
|
||||
data.ctx = ctx;
|
||||
data.values[0] = NULL;
|
||||
data.values[1] = NULL;
|
||||
|
||||
@@ -490,10 +507,11 @@ gtk_css_arg2_value_parse (GtkCssParser *parser,
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
gtk_css_argn_value_parse (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags,
|
||||
const char *function,
|
||||
guint type)
|
||||
gtk_css_argn_value_parse (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags,
|
||||
GtkCssNumberParseContext *ctx,
|
||||
const char *function,
|
||||
guint type)
|
||||
{
|
||||
ParseArgnData data;
|
||||
GtkCssValue *result = NULL;
|
||||
@@ -507,6 +525,7 @@ gtk_css_argn_value_parse (GtkCssParser *parser,
|
||||
/* This can only be handled at compute time, we allow '-' after all */
|
||||
data.flags = flags & ~GTK_CSS_POSITIVE_ONLY;
|
||||
data.values = g_ptr_array_new ();
|
||||
data.ctx = ctx;
|
||||
|
||||
if (gtk_css_parser_consume_function (parser, 1, G_MAXUINT, gtk_css_argn_value_parse_arg, &data))
|
||||
{
|
||||
@@ -535,4 +554,3 @@ gtk_css_argn_value_parse (GtkCssParser *parser,
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,21 +22,26 @@
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GtkCssValue * gtk_css_calc_value_parse (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags);
|
||||
GtkCssNumberParseFlags flags,
|
||||
GtkCssNumberParseContext *ctx);
|
||||
GtkCssValue * gtk_css_clamp_value_parse (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags,
|
||||
GtkCssNumberParseContext *ctx,
|
||||
guint type);
|
||||
GtkCssValue * gtk_css_round_value_parse (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags,
|
||||
GtkCssNumberParseContext *ctx,
|
||||
guint type);
|
||||
GtkCssValue * gtk_css_arg2_value_parse (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags,
|
||||
GtkCssNumberParseContext *ctx,
|
||||
guint min_args,
|
||||
guint max_args,
|
||||
const char *function,
|
||||
guint type);
|
||||
GtkCssValue * gtk_css_argn_value_parse (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags,
|
||||
GtkCssNumberParseContext *ctx,
|
||||
const char *function,
|
||||
guint type);
|
||||
|
||||
|
||||
@@ -0,0 +1,906 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2024 Red Hat, Inc.
|
||||
*
|
||||
* 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 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/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkcsscolorprivate.h"
|
||||
#include "gtkcolorutilsprivate.h"
|
||||
|
||||
/* {{{ Initialization */
|
||||
|
||||
void
|
||||
gtk_css_color_init (GtkCssColor *color,
|
||||
GtkCssColorSpace color_space,
|
||||
const float values[4])
|
||||
{
|
||||
gboolean missing[4] = { 0, };
|
||||
|
||||
/* look for powerless components */
|
||||
switch (color_space)
|
||||
{
|
||||
case GTK_CSS_COLOR_SPACE_SRGB:
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
case GTK_CSS_COLOR_SPACE_OKLAB:
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_HSL:
|
||||
if (fabs (values[2]) < 0.001)
|
||||
missing[0] = 1;
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_HWB:
|
||||
if (values[1] + values[2] > 99.999)
|
||||
missing[0] = 1;
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_OKLCH:
|
||||
if (fabs (values[1]) < 0.001)
|
||||
missing[2] = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
gtk_css_color_init_with_missing (color, color_space, values, missing);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* {{{ Utilities */
|
||||
|
||||
static inline void
|
||||
append_color_component (GString *string,
|
||||
const GtkCssColor *color,
|
||||
guint idx)
|
||||
{
|
||||
if (gtk_css_color_component_missing (color, idx))
|
||||
g_string_append (string, "none");
|
||||
else
|
||||
g_string_append_printf (string, "%g", gtk_css_color_get_component (color, idx));
|
||||
}
|
||||
|
||||
static void
|
||||
print_as_rgb (const GtkCssColor *color,
|
||||
GString *string)
|
||||
{
|
||||
GtkCssColor tmp;
|
||||
|
||||
gtk_css_color_convert (color, GTK_CSS_COLOR_SPACE_SRGB, &tmp);
|
||||
if (tmp.values[3] > 0.999)
|
||||
{
|
||||
g_string_append_printf (string, "rgb(%d,%d,%d)",
|
||||
(int)(0.5 + CLAMP (tmp.values[0], 0., 1.) * 255.),
|
||||
(int)(0.5 + CLAMP (tmp.values[1], 0., 1.) * 255.),
|
||||
(int)(0.5 + CLAMP (tmp.values[2], 0., 1.) * 255.));
|
||||
}
|
||||
else
|
||||
{
|
||||
char alpha[G_ASCII_DTOSTR_BUF_SIZE];
|
||||
|
||||
g_ascii_formatd (alpha, G_ASCII_DTOSTR_BUF_SIZE, "%g", CLAMP (tmp.values[3], 0, 1));
|
||||
|
||||
g_string_append_printf (string, "rgba(%d,%d,%d,%s)",
|
||||
(int)(0.5 + CLAMP (tmp.values[0], 0., 1.) * 255.),
|
||||
(int)(0.5 + CLAMP (tmp.values[1], 0., 1.) * 255.),
|
||||
(int)(0.5 + CLAMP (tmp.values[2], 0., 1.) * 255.),
|
||||
alpha);
|
||||
}
|
||||
}
|
||||
|
||||
GString *
|
||||
gtk_css_color_print (const GtkCssColor *color,
|
||||
gboolean serialize_as_rgb,
|
||||
GString *string)
|
||||
{
|
||||
GtkCssColorSpace print_color_space = color->color_space;
|
||||
GtkCssColor tmp;
|
||||
|
||||
switch (color->color_space)
|
||||
{
|
||||
case GTK_CSS_COLOR_SPACE_SRGB:
|
||||
case GTK_CSS_COLOR_SPACE_HSL:
|
||||
case GTK_CSS_COLOR_SPACE_HWB:
|
||||
if (serialize_as_rgb)
|
||||
{
|
||||
print_as_rgb (color, string);
|
||||
return string;
|
||||
}
|
||||
|
||||
print_color_space = GTK_CSS_COLOR_SPACE_SRGB;
|
||||
g_string_append (string, "color(srgb ");
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
g_string_append (string, "color(srgb-linear ");
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_OKLAB:
|
||||
g_string_append (string, "oklab(");
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_OKLCH:
|
||||
g_string_append (string, "oklch(");
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (print_color_space != color->color_space)
|
||||
gtk_css_color_convert (color, print_color_space, &tmp);
|
||||
else
|
||||
tmp = *color;
|
||||
|
||||
for (guint i = 0; i < 3; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
g_string_append_c (string, ' ');
|
||||
append_color_component (string, &tmp, i);
|
||||
}
|
||||
|
||||
if (gtk_css_color_component_missing (&tmp, 3) ||
|
||||
tmp.values[3] < 0.999)
|
||||
{
|
||||
g_string_append (string, " / ");
|
||||
append_color_component (string, &tmp, 3);
|
||||
}
|
||||
|
||||
g_string_append_c (string, ')');
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
char *
|
||||
gtk_css_color_to_string (const GtkCssColor *color)
|
||||
{
|
||||
return g_string_free (gtk_css_color_print (color, FALSE, g_string_new ("")), FALSE);
|
||||
}
|
||||
|
||||
const char *
|
||||
gtk_css_color_space_get_coord_name (GtkCssColorSpace color_space,
|
||||
guint coord)
|
||||
{
|
||||
if (coord == 3)
|
||||
return "alpha";
|
||||
|
||||
switch (color_space)
|
||||
{
|
||||
case GTK_CSS_COLOR_SPACE_SRGB:
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
switch (coord)
|
||||
{
|
||||
case 0: return "r";
|
||||
case 1: return "g";
|
||||
case 2: return "b";
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
case GTK_CSS_COLOR_SPACE_HSL:
|
||||
switch (coord)
|
||||
{
|
||||
case 0: return "h";
|
||||
case 1: return "s";
|
||||
case 2: return "l";
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
case GTK_CSS_COLOR_SPACE_HWB:
|
||||
switch (coord)
|
||||
{
|
||||
case 0: return "h";
|
||||
case 1: return "w";
|
||||
case 2: return "b";
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
case GTK_CSS_COLOR_SPACE_OKLAB:
|
||||
switch (coord)
|
||||
{
|
||||
case 0: return "l";
|
||||
case 1: return "a";
|
||||
case 2: return "b";
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
case GTK_CSS_COLOR_SPACE_OKLCH:
|
||||
switch (coord)
|
||||
{
|
||||
case 0: return "l";
|
||||
case 1: return "c";
|
||||
case 2: return "h";
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
color_space_is_polar (GtkCssColorSpace color_space)
|
||||
{
|
||||
switch (color_space)
|
||||
{
|
||||
case GTK_CSS_COLOR_SPACE_SRGB:
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
case GTK_CSS_COLOR_SPACE_OKLAB:
|
||||
return FALSE;
|
||||
case GTK_CSS_COLOR_SPACE_HSL:
|
||||
case GTK_CSS_COLOR_SPACE_HWB:
|
||||
case GTK_CSS_COLOR_SPACE_OKLCH:
|
||||
return TRUE;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* {{{ Color conversion */
|
||||
|
||||
static void
|
||||
convert_to_rectangular (GtkCssColor *output)
|
||||
{
|
||||
float v[4];
|
||||
gboolean no_missing[4] = { 0, };
|
||||
|
||||
switch (output->color_space)
|
||||
{
|
||||
case GTK_CSS_COLOR_SPACE_SRGB:
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
case GTK_CSS_COLOR_SPACE_OKLAB:
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_HSL:
|
||||
gtk_hsl_to_rgb (output->values[0],
|
||||
output->values[1] / 100,
|
||||
output->values[2] / 100,
|
||||
&v[0], &v[1], &v[2]);
|
||||
v[3] = output->values[3];
|
||||
gtk_css_color_init_with_missing (output, GTK_CSS_COLOR_SPACE_SRGB, v, no_missing);
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_HWB:
|
||||
gtk_hwb_to_rgb (output->values[0],
|
||||
output->values[1] / 100,
|
||||
output->values[2] / 100,
|
||||
&v[0], &v[1], &v[2]);
|
||||
v[3] = output->values[3];
|
||||
gtk_css_color_init_with_missing (output, GTK_CSS_COLOR_SPACE_SRGB, v, no_missing);
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_OKLCH:
|
||||
gtk_oklch_to_oklab (output->values[0],
|
||||
output->values[1],
|
||||
output->values[2],
|
||||
&v[0], &v[1], &v[2]);
|
||||
v[3] = output->values[3];
|
||||
gtk_css_color_init_with_missing (output, GTK_CSS_COLOR_SPACE_OKLAB, v, no_missing);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
convert_to_linear (GtkCssColor *output)
|
||||
{
|
||||
float v[4];
|
||||
|
||||
g_assert (output->color_space == GTK_CSS_COLOR_SPACE_SRGB ||
|
||||
output->color_space == GTK_CSS_COLOR_SPACE_SRGB_LINEAR ||
|
||||
output->color_space == GTK_CSS_COLOR_SPACE_OKLAB);
|
||||
|
||||
if (output->color_space == GTK_CSS_COLOR_SPACE_SRGB)
|
||||
{
|
||||
gtk_rgb_to_linear_srgb (output->values[0],
|
||||
output->values[1],
|
||||
output->values[2],
|
||||
&v[0], &v[1], &v[2]);
|
||||
v[3] = output->values[3];
|
||||
gtk_css_color_init (output, GTK_CSS_COLOR_SPACE_SRGB_LINEAR, v);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_linear (GtkCssColor *output,
|
||||
GtkCssColorSpace dest)
|
||||
{
|
||||
float v[4];
|
||||
|
||||
g_assert (output->color_space == GTK_CSS_COLOR_SPACE_SRGB_LINEAR ||
|
||||
output->color_space == GTK_CSS_COLOR_SPACE_OKLAB);
|
||||
|
||||
switch (dest)
|
||||
{
|
||||
case GTK_CSS_COLOR_SPACE_SRGB:
|
||||
case GTK_CSS_COLOR_SPACE_HSL:
|
||||
case GTK_CSS_COLOR_SPACE_HWB:
|
||||
gtk_linear_srgb_to_rgb (output->values[0],
|
||||
output->values[1],
|
||||
output->values[2],
|
||||
&v[0], &v[1], &v[2]);
|
||||
v[3] = output->values[3];
|
||||
gtk_css_color_init (output, GTK_CSS_COLOR_SPACE_SRGB, v);
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
case GTK_CSS_COLOR_SPACE_OKLAB:
|
||||
case GTK_CSS_COLOR_SPACE_OKLCH:
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_rectangular (GtkCssColor *output,
|
||||
GtkCssColorSpace dest)
|
||||
{
|
||||
float v[4];
|
||||
|
||||
switch (dest)
|
||||
{
|
||||
case GTK_CSS_COLOR_SPACE_SRGB:
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
case GTK_CSS_COLOR_SPACE_OKLAB:
|
||||
g_assert (output->color_space == dest);
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_HSL:
|
||||
g_assert (output->color_space == GTK_CSS_COLOR_SPACE_SRGB);
|
||||
gtk_rgb_to_hsl (output->values[0],
|
||||
output->values[1],
|
||||
output->values[2],
|
||||
&v[0], &v[1], &v[2]);
|
||||
v[1] *= 100;
|
||||
v[2] *= 100;
|
||||
v[3] = output->values[3];
|
||||
|
||||
gtk_css_color_init (output, dest, v);
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_HWB:
|
||||
g_assert (output->color_space == GTK_CSS_COLOR_SPACE_SRGB);
|
||||
gtk_rgb_to_hwb (output->values[0],
|
||||
output->values[1],
|
||||
output->values[2],
|
||||
&v[0], &v[1], &v[2]);
|
||||
|
||||
v[1] *= 100;
|
||||
v[2] *= 100;
|
||||
v[3] = output->values[3];
|
||||
|
||||
gtk_css_color_init (output, dest, v);
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_OKLCH:
|
||||
g_assert (output->color_space == GTK_CSS_COLOR_SPACE_OKLAB);
|
||||
gtk_oklab_to_oklch (output->values[0],
|
||||
output->values[1],
|
||||
output->values[2],
|
||||
&v[0], &v[1], &v[2]);
|
||||
v[3] = output->values[3];
|
||||
|
||||
gtk_css_color_init (output, dest, v);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
convert_linear_to_linear (GtkCssColor *output,
|
||||
GtkCssColorSpace dest)
|
||||
{
|
||||
GtkCssColorSpace dest_linear;
|
||||
float v[4];
|
||||
|
||||
if (dest == GTK_CSS_COLOR_SPACE_OKLCH ||
|
||||
dest == GTK_CSS_COLOR_SPACE_OKLAB)
|
||||
dest_linear = GTK_CSS_COLOR_SPACE_OKLAB;
|
||||
else
|
||||
dest_linear = GTK_CSS_COLOR_SPACE_SRGB_LINEAR;
|
||||
|
||||
if (dest_linear == GTK_CSS_COLOR_SPACE_SRGB_LINEAR &&
|
||||
output->color_space == GTK_CSS_COLOR_SPACE_OKLAB)
|
||||
{
|
||||
gtk_oklab_to_linear_srgb (output->values[0],
|
||||
output->values[1],
|
||||
output->values[2],
|
||||
&v[0], &v[1], &v[2]);
|
||||
v[3] = output->values[3];
|
||||
gtk_css_color_init (output, dest_linear, v);
|
||||
}
|
||||
else if (dest_linear == GTK_CSS_COLOR_SPACE_OKLAB &&
|
||||
output->color_space == GTK_CSS_COLOR_SPACE_SRGB_LINEAR)
|
||||
{
|
||||
gtk_linear_srgb_to_oklab (output->values[0],
|
||||
output->values[1],
|
||||
output->values[2],
|
||||
&v[0], &v[1], &v[2]);
|
||||
v[3] = output->values[3];
|
||||
gtk_css_color_init (output, dest_linear, v);
|
||||
}
|
||||
|
||||
g_assert (output->color_space == dest_linear);
|
||||
}
|
||||
|
||||
/* See https://www.w3.org/TR/css-color-4/#color-conversion */
|
||||
void
|
||||
gtk_css_color_convert (const GtkCssColor *input,
|
||||
GtkCssColorSpace dest,
|
||||
GtkCssColor *output)
|
||||
{
|
||||
gtk_css_color_init_from_color (output, input);
|
||||
|
||||
convert_to_rectangular (output);
|
||||
convert_to_linear (output);
|
||||
|
||||
/* FIXME: White point adaptation goes here */
|
||||
|
||||
g_assert (output->color_space == GTK_CSS_COLOR_SPACE_SRGB_LINEAR ||
|
||||
output->color_space == GTK_CSS_COLOR_SPACE_OKLAB);
|
||||
|
||||
convert_linear_to_linear (output, dest);
|
||||
convert_from_linear (output, dest);
|
||||
|
||||
/* FIXME: Gamut mapping goes here */
|
||||
|
||||
convert_from_rectangular (output, dest);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* {{{ Color interpolation */
|
||||
|
||||
static void
|
||||
adjust_hue (float *h1,
|
||||
float *h2,
|
||||
GtkCssHueInterpolation interp)
|
||||
{
|
||||
|
||||
switch (interp)
|
||||
{
|
||||
case GTK_CSS_HUE_INTERPOLATION_SHORTER:
|
||||
{
|
||||
float d = *h2 - *h1;
|
||||
|
||||
if (d > 180)
|
||||
*h1 += 360;
|
||||
else if (d < -180)
|
||||
*h2 += 360;
|
||||
}
|
||||
break;
|
||||
|
||||
case GTK_CSS_HUE_INTERPOLATION_LONGER:
|
||||
{
|
||||
float d = *h2 - *h1;
|
||||
|
||||
if (0 < d && d < 180)
|
||||
*h1 += 360;
|
||||
else if (-180 < d && d <= 0)
|
||||
*h2 += 360;
|
||||
}
|
||||
break;
|
||||
|
||||
case GTK_CSS_HUE_INTERPOLATION_INCREASING:
|
||||
if (*h2 < *h1)
|
||||
*h2 += 360;
|
||||
break;
|
||||
|
||||
case GTK_CSS_HUE_INTERPOLATION_DECREASING:
|
||||
if (*h1 < *h2)
|
||||
*h1 += 360;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
apply_hue_interpolation (GtkCssColor *from,
|
||||
GtkCssColor *to,
|
||||
GtkCssColorSpace in,
|
||||
GtkCssHueInterpolation interp)
|
||||
{
|
||||
switch (in)
|
||||
{
|
||||
case GTK_CSS_COLOR_SPACE_SRGB:
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
case GTK_CSS_COLOR_SPACE_OKLAB:
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_HSL:
|
||||
case GTK_CSS_COLOR_SPACE_HWB:
|
||||
adjust_hue (&from->values[0], &to->values[0], interp);
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_OKLCH:
|
||||
adjust_hue (&from->values[2], &to->values[2], interp);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
normalize_hue_component (float *v)
|
||||
{
|
||||
*v = fmod (*v, 360);
|
||||
if (*v < 0)
|
||||
*v += 360;
|
||||
}
|
||||
|
||||
static void
|
||||
normalize_hue (GtkCssColor *color)
|
||||
{
|
||||
switch (color->color_space)
|
||||
{
|
||||
case GTK_CSS_COLOR_SPACE_SRGB:
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
case GTK_CSS_COLOR_SPACE_OKLAB:
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_HSL:
|
||||
case GTK_CSS_COLOR_SPACE_HWB:
|
||||
normalize_hue_component (&color->values[0]);
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_OKLCH:
|
||||
normalize_hue_component (&color->values[2]);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
premultiply_component (GtkCssColor *color,
|
||||
guint i)
|
||||
{
|
||||
if ((color->missing & (1 << i)) != 0)
|
||||
return;
|
||||
|
||||
color->values[i] *= color->values[3];
|
||||
}
|
||||
|
||||
static void
|
||||
premultiply (GtkCssColor *color)
|
||||
{
|
||||
if (color->missing & (1 << 3))
|
||||
return;
|
||||
|
||||
switch (color->color_space)
|
||||
{
|
||||
case GTK_CSS_COLOR_SPACE_SRGB:
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
case GTK_CSS_COLOR_SPACE_OKLAB:
|
||||
premultiply_component (color, 0);
|
||||
premultiply_component (color, 1);
|
||||
premultiply_component (color, 2);
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_HSL:
|
||||
case GTK_CSS_COLOR_SPACE_HWB:
|
||||
premultiply_component (color, 1);
|
||||
premultiply_component (color, 2);
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_OKLCH:
|
||||
premultiply_component (color, 0);
|
||||
premultiply_component (color, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
unpremultiply_component (GtkCssColor *color,
|
||||
guint i)
|
||||
{
|
||||
if ((color->missing & (1 << i)) != 0)
|
||||
return;
|
||||
|
||||
color->values[i] /= color->values[3];
|
||||
}
|
||||
|
||||
static void
|
||||
unpremultiply (GtkCssColor *color)
|
||||
{
|
||||
if ((color->missing & (1 << 3)) != 0 || color->values[3] == 0)
|
||||
return;
|
||||
|
||||
switch (color->color_space)
|
||||
{
|
||||
case GTK_CSS_COLOR_SPACE_SRGB:
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
case GTK_CSS_COLOR_SPACE_OKLAB:
|
||||
unpremultiply_component (color, 0);
|
||||
unpremultiply_component (color, 1);
|
||||
unpremultiply_component (color, 2);
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_HSL:
|
||||
case GTK_CSS_COLOR_SPACE_HWB:
|
||||
unpremultiply_component (color, 1);
|
||||
unpremultiply_component (color, 2);
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_OKLCH:
|
||||
unpremultiply_component (color, 0);
|
||||
unpremultiply_component (color, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
collect_analogous_missing (const GtkCssColor *color,
|
||||
GtkCssColorSpace color_space,
|
||||
gboolean missing[4])
|
||||
{
|
||||
/* Coords for red, green, blue, lightness, colorfulness, hue,
|
||||
* opposite a, opposite b, alpha, for each of our colorspaces,
|
||||
*/
|
||||
static int analogous[][9] = {
|
||||
{ 0, 1, 2, -1, -1, -1, -1, -1, 3 }, /* srgb */
|
||||
{ 0, 1, 2, -1, -1, -1, -1, -1, 3 }, /* srgb-linear */
|
||||
{ -1, -1, -1, 2, 1, 0, -1, -1, 3 }, /* hsl */
|
||||
{ -1, -1, -1, -1, -1, 0, -1, -1, 3 }, /* hwb */
|
||||
{ -1, -1, -1, 0, -1, -1, 1, 2, 3 }, /* oklab */
|
||||
{ -1, -1, -1, 0, 1, 2, -1, -1, 3 }, /* oklch */
|
||||
|
||||
};
|
||||
|
||||
int *src = analogous[color->color_space];
|
||||
int *dest = analogous[color_space];
|
||||
|
||||
for (guint i = 0; i < 4; i++)
|
||||
missing[i] = 0;
|
||||
|
||||
for (guint i = 0; i < 4; i++)
|
||||
{
|
||||
if ((color->missing & (1 << i)) == 0)
|
||||
continue;
|
||||
|
||||
for (guint j = 0; j < 9; j++)
|
||||
{
|
||||
if (src[j] == i)
|
||||
{
|
||||
int idx = dest[j];
|
||||
|
||||
if (idx != -1)
|
||||
missing[idx] = TRUE;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* See https://www.w3.org/TR/css-color-4/#interpolation */
|
||||
void
|
||||
gtk_css_color_interpolate (const GtkCssColor *from,
|
||||
const GtkCssColor *to,
|
||||
float progress,
|
||||
GtkCssColorSpace in,
|
||||
GtkCssHueInterpolation interp,
|
||||
GtkCssColor *output)
|
||||
{
|
||||
GtkCssColor from1, to1;
|
||||
gboolean from_missing[4];
|
||||
gboolean to_missing[4];
|
||||
gboolean missing[4];
|
||||
float v[4];
|
||||
|
||||
collect_analogous_missing (from, in, from_missing);
|
||||
collect_analogous_missing (to, in, to_missing);
|
||||
|
||||
gtk_css_color_convert (from, in, &from1);
|
||||
gtk_css_color_convert (to, in, &to1);
|
||||
|
||||
for (guint i = 0; i < 4; i++)
|
||||
{
|
||||
gboolean m1 = from_missing[i];
|
||||
gboolean m2 = to_missing[i];
|
||||
|
||||
if (m1 && !m2)
|
||||
from1.values[i] = to1.values[i];
|
||||
else if (!m1 && m2)
|
||||
to1.values[i] = from1.values[i];
|
||||
|
||||
missing[i] = from_missing[i] && to_missing[i];
|
||||
}
|
||||
|
||||
from1.missing = 0;
|
||||
to1.missing = 0;
|
||||
|
||||
apply_hue_interpolation (&from1, &to1, in, interp);
|
||||
|
||||
premultiply (&from1);
|
||||
premultiply (&to1);
|
||||
|
||||
v[0] = from1.values[0] * (1 - progress) + to1.values[0] * progress;
|
||||
v[1] = from1.values[1] * (1 - progress) + to1.values[1] * progress;
|
||||
v[2] = from1.values[2] * (1 - progress) + to1.values[2] * progress;
|
||||
v[3] = from1.values[3] * (1 - progress) + to1.values[3] * progress;
|
||||
|
||||
gtk_css_color_init_with_missing (output, in, v, missing);
|
||||
|
||||
normalize_hue (output);
|
||||
|
||||
unpremultiply (output);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_hue_interpolation (GtkCssParser *parser,
|
||||
GtkCssHueInterpolation *interp)
|
||||
{
|
||||
const GtkCssToken *token = gtk_css_parser_get_token (parser);
|
||||
|
||||
if (gtk_css_token_is_ident (token, "shorter"))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
*interp = GTK_CSS_HUE_INTERPOLATION_SHORTER;
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "longer"))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
*interp = GTK_CSS_HUE_INTERPOLATION_LONGER;
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "increasing"))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
*interp = GTK_CSS_HUE_INTERPOLATION_INCREASING;
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "decreasing"))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
*interp = GTK_CSS_HUE_INTERPOLATION_DECREASING;
|
||||
}
|
||||
else
|
||||
{
|
||||
*interp = GTK_CSS_HUE_INTERPOLATION_SHORTER;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!gtk_css_parser_try_ident (parser, "hue"))
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected 'hue'");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_css_color_interpolation_method_parse (GtkCssParser *parser,
|
||||
GtkCssColorSpace *in,
|
||||
GtkCssHueInterpolation *interp)
|
||||
{
|
||||
const GtkCssToken *token;
|
||||
|
||||
if (!gtk_css_parser_try_ident (parser, "in"))
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected 'in'");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
token = gtk_css_parser_get_token (parser);
|
||||
|
||||
if (gtk_css_token_is_ident (token, "srgb"))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
*in = GTK_CSS_COLOR_SPACE_SRGB;
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "srgb-linear"))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
*in = GTK_CSS_COLOR_SPACE_SRGB_LINEAR;
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "hsl"))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
*in = GTK_CSS_COLOR_SPACE_HSL;
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "hwb"))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
*in = GTK_CSS_COLOR_SPACE_HWB;
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "oklch"))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
*in = GTK_CSS_COLOR_SPACE_OKLCH;
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "oklab"))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
*in = GTK_CSS_COLOR_SPACE_OKLAB;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Invalid color space");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (color_space_is_polar (*in))
|
||||
return parse_hue_interpolation (parser, interp);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gtk_css_color_interpolation_method_print (GtkCssColorSpace in,
|
||||
GtkCssHueInterpolation interp,
|
||||
GString *string)
|
||||
{
|
||||
g_string_append (string, "in ");
|
||||
|
||||
switch (in)
|
||||
{
|
||||
case GTK_CSS_COLOR_SPACE_SRGB:
|
||||
g_string_append (string, "srgb");
|
||||
break;
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
g_string_append (string, "srgb-linear");
|
||||
break;
|
||||
case GTK_CSS_COLOR_SPACE_HSL:
|
||||
g_string_append (string, "hsl");
|
||||
break;
|
||||
case GTK_CSS_COLOR_SPACE_HWB:
|
||||
g_string_append (string, "hwb");
|
||||
break;
|
||||
case GTK_CSS_COLOR_SPACE_OKLCH:
|
||||
g_string_append (string, "oklch");
|
||||
break;
|
||||
case GTK_CSS_COLOR_SPACE_OKLAB:
|
||||
g_string_append (string, "oklab");
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (!color_space_is_polar (in))
|
||||
return;
|
||||
|
||||
switch (interp)
|
||||
{
|
||||
case GTK_CSS_HUE_INTERPOLATION_SHORTER:
|
||||
/* shorter is the default mode, don't print it */
|
||||
break;
|
||||
case GTK_CSS_HUE_INTERPOLATION_LONGER:
|
||||
g_string_append (string, " longer hue");
|
||||
break;
|
||||
case GTK_CSS_HUE_INTERPOLATION_INCREASING:
|
||||
g_string_append (string, " increasing hue");
|
||||
break;
|
||||
case GTK_CSS_HUE_INTERPOLATION_DECREASING:
|
||||
g_string_append (string, " decreasing hue");
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* vim:set foldmethod=marker expandtab: */
|
||||
@@ -0,0 +1,125 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2040 Red Hat, Inc.
|
||||
*
|
||||
* 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 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "gtk/css/gtkcssparserprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum {
|
||||
GTK_CSS_COLOR_SPACE_SRGB,
|
||||
GTK_CSS_COLOR_SPACE_SRGB_LINEAR,
|
||||
GTK_CSS_COLOR_SPACE_HSL,
|
||||
GTK_CSS_COLOR_SPACE_HWB,
|
||||
GTK_CSS_COLOR_SPACE_OKLAB,
|
||||
GTK_CSS_COLOR_SPACE_OKLCH,
|
||||
} GtkCssColorSpace;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkCssColorSpace color_space;
|
||||
float values[4];
|
||||
guint missing;
|
||||
} GtkCssColor;
|
||||
|
||||
static inline gboolean
|
||||
gtk_css_color_equal (const GtkCssColor *color1,
|
||||
const GtkCssColor *color2)
|
||||
{
|
||||
return color1->color_space == color2->color_space &&
|
||||
color1->missing == color2->missing &&
|
||||
memcmp (color1->values, color2->values, sizeof (float) * 4) == 0;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
gtk_css_color_component_missing (const GtkCssColor *color,
|
||||
guint idx)
|
||||
{
|
||||
return (color->missing & (1 << idx)) != 0;
|
||||
}
|
||||
|
||||
static inline float
|
||||
gtk_css_color_get_component (const GtkCssColor *color,
|
||||
guint idx)
|
||||
{
|
||||
return color->values[idx];
|
||||
}
|
||||
|
||||
static inline void
|
||||
gtk_css_color_init_with_missing (GtkCssColor *color,
|
||||
GtkCssColorSpace color_space,
|
||||
const float values[4],
|
||||
gboolean missing[4])
|
||||
{
|
||||
color->color_space = color_space;
|
||||
for (guint i = 0; i < 4; i++)
|
||||
color->values[i] = missing[i] ? 0 : values[i];
|
||||
color->missing = missing[0] | (missing[1] << 1) | (missing[2] << 2) | (missing[3] << 3);
|
||||
}
|
||||
|
||||
static inline void
|
||||
gtk_css_color_init_from_color (GtkCssColor *color,
|
||||
const GtkCssColor *src)
|
||||
{
|
||||
memcpy (color, src, sizeof (GtkCssColor));
|
||||
}
|
||||
|
||||
void gtk_css_color_init (GtkCssColor *color,
|
||||
GtkCssColorSpace color_space,
|
||||
const float values[4]);
|
||||
|
||||
GString * gtk_css_color_print (const GtkCssColor *color,
|
||||
gboolean serialize_as_rgb,
|
||||
GString *string);
|
||||
|
||||
char * gtk_css_color_to_string (const GtkCssColor *color);
|
||||
|
||||
void gtk_css_color_convert (const GtkCssColor *input,
|
||||
GtkCssColorSpace dest,
|
||||
GtkCssColor *output);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GTK_CSS_HUE_INTERPOLATION_SHORTER,
|
||||
GTK_CSS_HUE_INTERPOLATION_LONGER,
|
||||
GTK_CSS_HUE_INTERPOLATION_INCREASING,
|
||||
GTK_CSS_HUE_INTERPOLATION_DECREASING,
|
||||
} GtkCssHueInterpolation;
|
||||
|
||||
void gtk_css_color_interpolate (const GtkCssColor *from,
|
||||
const GtkCssColor *to,
|
||||
float progress,
|
||||
GtkCssColorSpace in,
|
||||
GtkCssHueInterpolation interp,
|
||||
GtkCssColor *output);
|
||||
|
||||
const char * gtk_css_color_space_get_coord_name (GtkCssColorSpace color_space,
|
||||
guint coord);
|
||||
|
||||
gboolean gtk_css_color_interpolation_method_parse (GtkCssParser *parser,
|
||||
GtkCssColorSpace *in,
|
||||
GtkCssHueInterpolation *interp);
|
||||
|
||||
void gtk_css_color_interpolation_method_print (GtkCssColorSpace in,
|
||||
GtkCssHueInterpolation interp,
|
||||
GString *string);
|
||||
|
||||
G_END_DECLS
|
||||
+1525
-145
File diff suppressed because it is too large
Load Diff
@@ -21,31 +21,37 @@
|
||||
#include "gtk/css/gtkcsstokenizerprivate.h"
|
||||
#include "gtk/css/gtkcssparserprivate.h"
|
||||
#include "gtkcssvalueprivate.h"
|
||||
#include "gtkcsscolorprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
GtkCssValue * gtk_css_color_value_new_transparent (void) G_GNUC_PURE;
|
||||
GtkCssValue * gtk_css_color_value_new_white (void) G_GNUC_PURE;
|
||||
GtkCssValue * gtk_css_color_value_new_literal (const GdkRGBA *color) G_GNUC_PURE;
|
||||
GtkCssValue * gtk_css_color_value_new_name (const char *name) G_GNUC_PURE;
|
||||
GtkCssValue * gtk_css_color_value_new_shade (GtkCssValue *color,
|
||||
double factor) G_GNUC_PURE;
|
||||
GtkCssValue * gtk_css_color_value_new_alpha (GtkCssValue *color,
|
||||
double factor) G_GNUC_PURE;
|
||||
GtkCssValue * gtk_css_color_value_new_mix (GtkCssValue *color1,
|
||||
GtkCssValue *color2,
|
||||
double factor) G_GNUC_PURE;
|
||||
GtkCssValue * gtk_css_color_value_new_current_color (void) G_GNUC_PURE;
|
||||
GtkCssValue * gtk_css_color_value_new_name (const char *name) G_GNUC_PURE;
|
||||
|
||||
gboolean gtk_css_color_value_can_parse (GtkCssParser *parser);
|
||||
GtkCssValue * gtk_css_color_value_parse (GtkCssParser *parser);
|
||||
|
||||
GtkCssValue * gtk_css_color_value_resolve (GtkCssValue *color,
|
||||
GtkStyleProvider *provider,
|
||||
GtkCssValue *current);
|
||||
GtkCssValue * gtk_css_color_value_resolve (GtkCssValue *color,
|
||||
guint property_id,
|
||||
GtkCssComputeContext *context,
|
||||
GtkCssValue *current);
|
||||
|
||||
const GdkRGBA * gtk_css_color_value_get_rgba (const GtkCssValue *color) G_GNUC_CONST;
|
||||
|
||||
GtkCssValue * gtk_css_color_value_new_color (GtkCssColorSpace color_space,
|
||||
gboolean serialize_as_rgb,
|
||||
const float values[4],
|
||||
gboolean missing[4]) G_GNUC_PURE;
|
||||
|
||||
const GtkCssColor *
|
||||
gtk_css_color_value_get_color (const GtkCssValue *color) G_GNUC_CONST;
|
||||
|
||||
float gtk_css_color_value_get_coord (const GtkCssValue *color,
|
||||
GtkCssColorSpace color_space,
|
||||
gboolean legacy_srgb,
|
||||
guint coord);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+134
-30
@@ -22,6 +22,7 @@
|
||||
#include "gtkcsscalcvalueprivate.h"
|
||||
#include "gtkcssenumvalueprivate.h"
|
||||
#include "gtkcssdimensionvalueprivate.h"
|
||||
#include "gtkcsscolorvalueprivate.h"
|
||||
#include "gtkcssstyleprivate.h"
|
||||
#include "gtkprivate.h"
|
||||
|
||||
@@ -69,6 +70,7 @@ typedef enum {
|
||||
TYPE_EXP,
|
||||
TYPE_LOG,
|
||||
TYPE_HYPOT,
|
||||
TYPE_COLOR_COORD,
|
||||
} NumberValueType;
|
||||
|
||||
static const char *function_name[] = {
|
||||
@@ -110,6 +112,12 @@ struct _GtkCssValue {
|
||||
guint n_terms;
|
||||
GtkCssValue *terms[1];
|
||||
} calc;
|
||||
struct {
|
||||
GtkCssValue *color;
|
||||
GtkCssColorSpace color_space;
|
||||
guint coord : 16;
|
||||
guint legacy_rgb_scale : 1;
|
||||
} color_coord;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -140,7 +148,11 @@ gtk_css_calc_value_new (guint type,
|
||||
static void
|
||||
gtk_css_value_number_free (GtkCssValue *number)
|
||||
{
|
||||
if (number->type != TYPE_DIMENSION)
|
||||
if (number->type == TYPE_COLOR_COORD)
|
||||
{
|
||||
gtk_css_value_unref (number->color_coord.color);
|
||||
}
|
||||
else if (number->type != TYPE_DIMENSION)
|
||||
{
|
||||
for (guint i = 0; i < number->calc.n_terms; i++)
|
||||
{
|
||||
@@ -310,7 +322,21 @@ gtk_css_value_number_compute (GtkCssValue *number,
|
||||
GtkCssStyle *style = context->style;
|
||||
GtkCssStyle *parent_style = context->parent_style;
|
||||
|
||||
if (number->type != TYPE_DIMENSION)
|
||||
if (number->type == TYPE_COLOR_COORD)
|
||||
{
|
||||
GtkCssValue *color;
|
||||
float v;
|
||||
|
||||
color = gtk_css_value_compute (number->color_coord.color, property_id, context);
|
||||
v = gtk_css_color_value_get_coord (color,
|
||||
number->color_coord.color_space,
|
||||
number->color_coord.legacy_rgb_scale,
|
||||
number->color_coord.coord);
|
||||
gtk_css_value_unref (color);
|
||||
|
||||
return gtk_css_number_value_new (v, GTK_CSS_NUMBER);
|
||||
}
|
||||
else if (number->type != TYPE_DIMENSION)
|
||||
{
|
||||
const guint n_terms = number->calc.n_terms;
|
||||
GtkCssValue *result;
|
||||
@@ -520,6 +546,10 @@ gtk_css_value_number_print (const GtkCssValue *value,
|
||||
g_string_append_c (string, ')');
|
||||
break;
|
||||
|
||||
case TYPE_COLOR_COORD:
|
||||
g_string_append (string, gtk_css_color_space_get_coord_name (value->color_coord.color_space, value->color_coord.coord));
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
const char *sep = value->type == TYPE_CALC ? " + " : (value->type == TYPE_PRODUCT ? " * " : ", ");
|
||||
@@ -871,6 +901,7 @@ gtk_css_number_value_get_dimension (const GtkCssValue *value)
|
||||
case TYPE_SQRT:
|
||||
case TYPE_POW:
|
||||
case TYPE_LOG:
|
||||
case TYPE_COLOR_COORD:
|
||||
return GTK_CSS_DIMENSION_NUMBER;
|
||||
|
||||
case TYPE_ASIN:
|
||||
@@ -887,7 +918,11 @@ gtk_css_number_value_get_dimension (const GtkCssValue *value)
|
||||
gboolean
|
||||
gtk_css_number_value_has_percent (const GtkCssValue *value)
|
||||
{
|
||||
if (value->type == TYPE_DIMENSION)
|
||||
if (value->type == TYPE_COLOR_COORD)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else if (value->type == TYPE_DIMENSION)
|
||||
{
|
||||
return gtk_css_unit_get_dimension (value->dimension.unit) == GTK_CSS_DIMENSION_PERCENTAGE;
|
||||
}
|
||||
@@ -1015,11 +1050,11 @@ gtk_css_number_value_multiply (GtkCssValue *value,
|
||||
break;
|
||||
}
|
||||
|
||||
return gtk_css_math_value_new (TYPE_PRODUCT, 0,
|
||||
(GtkCssValue *[]) {
|
||||
gtk_css_value_ref (value),
|
||||
gtk_css_number_value_new (factor, GTK_CSS_NUMBER)
|
||||
}, 2);
|
||||
return gtk_css_math_value_new (TYPE_PRODUCT, 0,
|
||||
(GtkCssValue *[]) {
|
||||
gtk_css_value_ref (value),
|
||||
gtk_css_number_value_new (factor, GTK_CSS_NUMBER)
|
||||
}, 2);
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
@@ -1314,7 +1349,7 @@ gtk_css_arg2_value_new (guint type,
|
||||
return gtk_css_dimension_value_new (v, unit);
|
||||
}
|
||||
|
||||
/* This funciton is called at parsing time, so units are not
|
||||
/* This function is called at parsing time, so units are not
|
||||
* canonical, and length values can't necessarily be unified.
|
||||
*/
|
||||
GtkCssValue *
|
||||
@@ -1326,6 +1361,7 @@ gtk_css_math_value_new (guint type,
|
||||
switch ((NumberValueType) type)
|
||||
{
|
||||
case TYPE_DIMENSION:
|
||||
case TYPE_COLOR_COORD:
|
||||
g_assert_not_reached ();
|
||||
|
||||
case TYPE_ROUND:
|
||||
@@ -1407,6 +1443,16 @@ gtk_css_number_value_can_parse (GtkCssParser *parser)
|
||||
GtkCssValue *
|
||||
gtk_css_number_value_parse (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags)
|
||||
{
|
||||
GtkCssNumberParseContext ctx = { NULL, 0, FALSE };
|
||||
|
||||
return gtk_css_number_value_parse_with_context (parser, flags, &ctx);
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
gtk_css_number_value_parse_with_context (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags,
|
||||
GtkCssNumberParseContext *ctx)
|
||||
{
|
||||
const GtkCssToken *token = gtk_css_parser_get_token (parser);
|
||||
|
||||
@@ -1415,47 +1461,47 @@ gtk_css_number_value_parse (GtkCssParser *parser,
|
||||
const char *name = gtk_css_token_get_string (token);
|
||||
|
||||
if (g_ascii_strcasecmp (name, "calc") == 0)
|
||||
return gtk_css_calc_value_parse (parser, flags);
|
||||
return gtk_css_calc_value_parse (parser, flags, ctx);
|
||||
else if (g_ascii_strcasecmp (name, "min") == 0)
|
||||
return gtk_css_argn_value_parse (parser, flags, "min", TYPE_MIN);
|
||||
return gtk_css_argn_value_parse (parser, flags, ctx, "min", TYPE_MIN);
|
||||
else if (g_ascii_strcasecmp (name, "max") == 0)
|
||||
return gtk_css_argn_value_parse (parser, flags, "max", TYPE_MAX);
|
||||
return gtk_css_argn_value_parse (parser, flags, ctx, "max", TYPE_MAX);
|
||||
else if (g_ascii_strcasecmp (name, "hypot") == 0)
|
||||
return gtk_css_argn_value_parse (parser, flags, "hypot", TYPE_HYPOT);
|
||||
return gtk_css_argn_value_parse (parser, flags, ctx, "hypot", TYPE_HYPOT);
|
||||
else if (g_ascii_strcasecmp (name, "clamp") == 0)
|
||||
return gtk_css_clamp_value_parse (parser, flags, TYPE_CLAMP);
|
||||
return gtk_css_clamp_value_parse (parser, flags, ctx, TYPE_CLAMP);
|
||||
else if (g_ascii_strcasecmp (name, "round") == 0)
|
||||
return gtk_css_round_value_parse (parser, flags, TYPE_ROUND);
|
||||
return gtk_css_round_value_parse (parser, flags, ctx, TYPE_ROUND);
|
||||
else if (g_ascii_strcasecmp (name, "mod") == 0)
|
||||
return gtk_css_arg2_value_parse (parser, flags, 2, 2, "mod", TYPE_MOD);
|
||||
return gtk_css_arg2_value_parse (parser, flags, ctx, 2, 2, "mod", TYPE_MOD);
|
||||
else if (g_ascii_strcasecmp (name, "rem") == 0)
|
||||
return gtk_css_arg2_value_parse (parser, flags, 2, 2, "rem", TYPE_REM);
|
||||
return gtk_css_arg2_value_parse (parser, flags, ctx, 2, 2, "rem", TYPE_REM);
|
||||
else if (g_ascii_strcasecmp (name, "abs") == 0)
|
||||
return gtk_css_arg2_value_parse (parser, flags, 1, 1, "abs", TYPE_ABS);
|
||||
return gtk_css_arg2_value_parse (parser, flags, ctx, 1, 1, "abs", TYPE_ABS);
|
||||
else if ((flags & GTK_CSS_PARSE_NUMBER) && g_ascii_strcasecmp (name, "sign") == 0)
|
||||
return gtk_css_arg2_value_parse (parser, GTK_CSS_PARSE_NUMBER|GTK_CSS_PARSE_DIMENSION|GTK_CSS_PARSE_PERCENT, 1, 1, "sign", TYPE_SIGN);
|
||||
return gtk_css_arg2_value_parse (parser, GTK_CSS_PARSE_NUMBER|GTK_CSS_PARSE_DIMENSION|GTK_CSS_PARSE_PERCENT, ctx, 1, 1, "sign", TYPE_SIGN);
|
||||
else if ((flags & GTK_CSS_PARSE_NUMBER) && g_ascii_strcasecmp (name, "sin") == 0)
|
||||
return gtk_css_arg2_value_parse (parser, GTK_CSS_PARSE_NUMBER|GTK_CSS_PARSE_ANGLE, 1, 1, "sin", TYPE_SIN);
|
||||
return gtk_css_arg2_value_parse (parser, GTK_CSS_PARSE_NUMBER|GTK_CSS_PARSE_ANGLE, ctx, 1, 1, "sin", TYPE_SIN);
|
||||
else if ((flags & GTK_CSS_PARSE_NUMBER) && g_ascii_strcasecmp (name, "cos") == 0)
|
||||
return gtk_css_arg2_value_parse (parser, GTK_CSS_PARSE_NUMBER|GTK_CSS_PARSE_ANGLE, 1, 1, "cos", TYPE_COS);
|
||||
return gtk_css_arg2_value_parse (parser, GTK_CSS_PARSE_NUMBER|GTK_CSS_PARSE_ANGLE, ctx, 1, 1, "cos", TYPE_COS);
|
||||
else if ((flags & GTK_CSS_PARSE_NUMBER) && g_ascii_strcasecmp (name, "tan") == 0)
|
||||
return gtk_css_arg2_value_parse (parser, GTK_CSS_PARSE_NUMBER|GTK_CSS_PARSE_ANGLE, 1, 1, "tan", TYPE_TAN);
|
||||
return gtk_css_arg2_value_parse (parser, GTK_CSS_PARSE_NUMBER|GTK_CSS_PARSE_ANGLE, ctx, 1, 1, "tan", TYPE_TAN);
|
||||
else if ((flags & GTK_CSS_PARSE_ANGLE) && g_ascii_strcasecmp (name, "asin") == 0)
|
||||
return gtk_css_arg2_value_parse (parser, GTK_CSS_PARSE_NUMBER, 1, 1, "asin", TYPE_ASIN);
|
||||
return gtk_css_arg2_value_parse (parser, GTK_CSS_PARSE_NUMBER, ctx, 1, 1, "asin", TYPE_ASIN);
|
||||
else if ((flags & GTK_CSS_PARSE_ANGLE) && g_ascii_strcasecmp (name, "acos") == 0)
|
||||
return gtk_css_arg2_value_parse (parser, GTK_CSS_PARSE_NUMBER, 1, 1, "acos", TYPE_ACOS);
|
||||
return gtk_css_arg2_value_parse (parser, GTK_CSS_PARSE_NUMBER, ctx, 1, 1, "acos", TYPE_ACOS);
|
||||
else if ((flags & GTK_CSS_PARSE_ANGLE) && g_ascii_strcasecmp (name, "atan") == 0)
|
||||
return gtk_css_arg2_value_parse (parser, GTK_CSS_PARSE_NUMBER, 1, 1, "atan", TYPE_ATAN);
|
||||
return gtk_css_arg2_value_parse (parser, GTK_CSS_PARSE_NUMBER, ctx, 1, 1, "atan", TYPE_ATAN);
|
||||
else if ((flags & GTK_CSS_PARSE_ANGLE) && g_ascii_strcasecmp (name, "atan2") == 0)
|
||||
return gtk_css_arg2_value_parse (parser, GTK_CSS_PARSE_NUMBER|GTK_CSS_PARSE_DIMENSION|GTK_CSS_PARSE_PERCENT, 2, 2, "atan2", TYPE_ATAN2);
|
||||
return gtk_css_arg2_value_parse (parser, GTK_CSS_PARSE_NUMBER|GTK_CSS_PARSE_DIMENSION|GTK_CSS_PARSE_PERCENT, ctx, 2, 2, "atan2", TYPE_ATAN2);
|
||||
else if ((flags & GTK_CSS_PARSE_NUMBER) && g_ascii_strcasecmp (name, "pow") == 0)
|
||||
return gtk_css_arg2_value_parse (parser, GTK_CSS_PARSE_NUMBER, 2, 2, "pow", TYPE_POW);
|
||||
return gtk_css_arg2_value_parse (parser, GTK_CSS_PARSE_NUMBER, ctx, 2, 2, "pow", TYPE_POW);
|
||||
else if ((flags & GTK_CSS_PARSE_NUMBER) && g_ascii_strcasecmp (name, "sqrt") == 0)
|
||||
return gtk_css_arg2_value_parse (parser, GTK_CSS_PARSE_NUMBER, 1, 1, "sqrt", TYPE_SQRT);
|
||||
return gtk_css_arg2_value_parse (parser, GTK_CSS_PARSE_NUMBER, ctx, 1, 1, "sqrt", TYPE_SQRT);
|
||||
else if ((flags & GTK_CSS_PARSE_NUMBER) && g_ascii_strcasecmp (name, "exp") == 0)
|
||||
return gtk_css_arg2_value_parse (parser, GTK_CSS_PARSE_NUMBER, 1, 1, "exp", TYPE_EXP);
|
||||
return gtk_css_arg2_value_parse (parser, GTK_CSS_PARSE_NUMBER, ctx, 1, 1, "exp", TYPE_EXP);
|
||||
else if ((flags & GTK_CSS_PARSE_NUMBER) && g_ascii_strcasecmp (name, "log") == 0)
|
||||
return gtk_css_arg2_value_parse (parser, GTK_CSS_PARSE_NUMBER, 1, 2, "log", TYPE_LOG);
|
||||
return gtk_css_arg2_value_parse (parser, GTK_CSS_PARSE_NUMBER, ctx, 1, 2, "log", TYPE_LOG);
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
|
||||
{
|
||||
@@ -1479,6 +1525,18 @@ gtk_css_number_value_parse (GtkCssParser *parser,
|
||||
return gtk_css_number_value_new (constants[i].value, GTK_CSS_NUMBER);
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->color)
|
||||
{
|
||||
for (guint i = 0; i < 4; i++)
|
||||
{
|
||||
if (g_ascii_strcasecmp (name, gtk_css_color_space_get_coord_name (ctx->color_space, i)) == 0)
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return gtk_css_number_value_new_color_component (ctx->color, ctx->color_space, ctx->legacy_rgb_scale, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return gtk_css_dimension_value_parse (parser, flags);
|
||||
@@ -1710,11 +1768,27 @@ gtk_css_number_value_get (const GtkCssValue *value,
|
||||
return sqrt (acc);
|
||||
}
|
||||
|
||||
case TYPE_COLOR_COORD:
|
||||
return gtk_css_color_value_get_coord (value->color_coord.color,
|
||||
value->color_coord.color_space,
|
||||
value->color_coord.legacy_rgb_scale,
|
||||
value->color_coord.coord);
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
double
|
||||
gtk_css_number_value_get_canonical (GtkCssValue *number,
|
||||
double one_hundred_percent)
|
||||
{
|
||||
if (number->type == TYPE_DIMENSION && number->dimension.unit != GTK_CSS_PERCENT)
|
||||
return get_converted_value (number, canonical_unit (number->dimension.unit));
|
||||
|
||||
return gtk_css_number_value_get (number, one_hundred_percent);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_css_dimension_value_is_zero (const GtkCssValue *value)
|
||||
{
|
||||
@@ -1811,3 +1885,33 @@ _sign (double a)
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
gtk_css_number_value_new_color_component (GtkCssValue *color,
|
||||
GtkCssColorSpace color_space,
|
||||
gboolean legacy_rgb_scale,
|
||||
guint coord)
|
||||
{
|
||||
if (gtk_css_value_is_computed (color))
|
||||
{
|
||||
float v;
|
||||
|
||||
v = gtk_css_color_value_get_coord (color, color_space, legacy_rgb_scale, coord);
|
||||
|
||||
return gtk_css_number_value_new (v, GTK_CSS_NUMBER);
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkCssValue *result;
|
||||
|
||||
result = gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_NUMBER);
|
||||
result->type = TYPE_COLOR_COORD;
|
||||
result->color_coord.color_space = color_space;
|
||||
result->color_coord.color = gtk_css_value_ref (color);
|
||||
result->color_coord.coord = coord;
|
||||
result->color_coord.legacy_rgb_scale = legacy_rgb_scale;
|
||||
result->is_computed = FALSE;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "gtk/css/gtkcssparserprivate.h"
|
||||
#include "gtkcsstypesprivate.h"
|
||||
#include "gtkcssvalueprivate.h"
|
||||
#include "gtkcsscolorprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -36,6 +37,14 @@ typedef enum /*< skip >*/ {
|
||||
GTK_CSS_PARSE_TIME = (1 << 5)
|
||||
} GtkCssNumberParseFlags;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Context needed when parsing numbers */
|
||||
GtkCssValue *color;
|
||||
GtkCssColorSpace color_space;
|
||||
gboolean legacy_rgb_scale; /* r, g, b must be scaled to 255 */
|
||||
} GtkCssNumberParseContext;
|
||||
|
||||
#define GTK_CSS_PARSE_DIMENSION (GTK_CSS_PARSE_LENGTH|GTK_CSS_PARSE_ANGLE|GTK_CSS_PARSE_TIME)
|
||||
|
||||
GtkCssValue * gtk_css_dimension_value_new (double value,
|
||||
@@ -47,6 +56,10 @@ gboolean gtk_css_number_value_can_parse (GtkCssParser *par
|
||||
GtkCssValue * gtk_css_number_value_parse (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags);
|
||||
|
||||
GtkCssValue * gtk_css_number_value_parse_with_context (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags,
|
||||
GtkCssNumberParseContext *context);
|
||||
|
||||
GtkCssDimension gtk_css_number_value_get_dimension (const GtkCssValue *value) G_GNUC_PURE;
|
||||
gboolean gtk_css_number_value_has_percent (const GtkCssValue *value) G_GNUC_PURE;
|
||||
GtkCssValue * gtk_css_number_value_multiply (GtkCssValue *value,
|
||||
@@ -57,9 +70,16 @@ GtkCssValue * gtk_css_number_value_try_add (GtkCssValue *val
|
||||
GtkCssValue *value2);
|
||||
double gtk_css_number_value_get (const GtkCssValue *number,
|
||||
double one_hundred_percent) G_GNUC_PURE;
|
||||
double gtk_css_number_value_get_canonical (GtkCssValue *number,
|
||||
double one_hundred_percent) G_GNUC_PURE;
|
||||
|
||||
gboolean gtk_css_dimension_value_is_zero (const GtkCssValue *value) G_GNUC_PURE;
|
||||
|
||||
GtkCssValue * gtk_css_number_value_new_color_component (GtkCssValue *color,
|
||||
GtkCssColorSpace color_space,
|
||||
gboolean legacy_srgb,
|
||||
guint coord);
|
||||
|
||||
enum {
|
||||
ROUND_NEAREST,
|
||||
ROUND_UP,
|
||||
|
||||
+16
-19
@@ -52,6 +52,9 @@
|
||||
#define GDK_ARRAY_PREALLOC 64
|
||||
#include "gdk/gdkarrayimpl.c"
|
||||
|
||||
/* For lack of a better place, assert here that these two definitions match */
|
||||
G_STATIC_ASSERT (GTK_DEBUG_CSS == GTK_CSS_PARSER_DEBUG_CSS);
|
||||
|
||||
/**
|
||||
* GtkCssProvider:
|
||||
*
|
||||
@@ -124,7 +127,6 @@ struct _GtkCssScanner
|
||||
GtkCssProvider *provider;
|
||||
GtkCssParser *parser;
|
||||
GtkCssScanner *parent;
|
||||
gboolean may_have_var;
|
||||
};
|
||||
|
||||
struct _GtkCssProviderPrivate
|
||||
@@ -185,10 +187,12 @@ gtk_css_provider_parsing_error (GtkCssProvider *provider,
|
||||
{
|
||||
char *s = gtk_css_section_to_string (section);
|
||||
|
||||
g_warning ("Theme parser %s: %s: %s",
|
||||
error->domain == GTK_CSS_PARSER_WARNING ? "warning" : "error",
|
||||
s,
|
||||
error->message);
|
||||
if (GTK_DEBUG_CHECK (CSS) ||
|
||||
!g_error_matches (error, GTK_CSS_PARSER_WARNING, GTK_CSS_PARSER_WARNING_DEPRECATED))
|
||||
g_warning ("Theme parser %s: %s: %s",
|
||||
error->domain == GTK_CSS_PARSER_WARNING ? "warning" : "error",
|
||||
s,
|
||||
error->message);
|
||||
|
||||
g_free (s);
|
||||
}
|
||||
@@ -219,6 +223,9 @@ gtk_css_provider_class_init (GtkCssProviderClass *klass)
|
||||
*
|
||||
* Signals that a parsing error occurred.
|
||||
*
|
||||
* The expected error values are in the [error@Gtk.CssParserError]
|
||||
* and [enum@Gtk.CssParserWarning] enumerations.
|
||||
*
|
||||
* The @path, @line and @position describe the actual location of
|
||||
* the error as accurately as possible.
|
||||
*
|
||||
@@ -227,6 +234,9 @@ gtk_css_provider_class_init (GtkCssProviderClass *klass)
|
||||
* even all of it to not be parsed at all. So it is a useful idea
|
||||
* to check that the parsing succeeds by connecting to this signal.
|
||||
*
|
||||
* Errors in the [enum@Gtk.CssParserWarning] enumeration should not
|
||||
* be treated as fatal errors.
|
||||
*
|
||||
* Note that this signal may be emitted at any time as the css provider
|
||||
* may opt to defer parsing parts or all of the input to a later time
|
||||
* than when a loading function was called.
|
||||
@@ -393,17 +403,6 @@ gtk_css_scanner_parser_error (GtkCssParser *parser,
|
||||
gtk_css_section_unref (section);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_for_var (GBytes *bytes)
|
||||
{
|
||||
const char *data;
|
||||
gsize len;
|
||||
|
||||
data = g_bytes_get_data (bytes, &len);
|
||||
|
||||
return memmem (data, len, "var(", 4) != NULL;
|
||||
}
|
||||
|
||||
static GtkCssScanner *
|
||||
gtk_css_scanner_new (GtkCssProvider *provider,
|
||||
GtkCssScanner *parent,
|
||||
@@ -417,7 +416,6 @@ gtk_css_scanner_new (GtkCssProvider *provider,
|
||||
g_object_ref (provider);
|
||||
scanner->provider = provider;
|
||||
scanner->parent = parent;
|
||||
scanner->may_have_var = check_for_var (bytes);
|
||||
|
||||
scanner->parser = gtk_css_parser_new_for_bytes (bytes,
|
||||
file,
|
||||
@@ -947,8 +945,7 @@ parse_declaration (GtkCssScanner *scanner,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (scanner->may_have_var &&
|
||||
gtk_css_parser_has_references (scanner->parser))
|
||||
if (gtk_css_parser_has_references (scanner->parser))
|
||||
{
|
||||
GtkCssLocation start_location;
|
||||
GtkCssVariableValue *var_value;
|
||||
|
||||
@@ -220,15 +220,25 @@ parser_error (GtkCssParser *parser,
|
||||
{
|
||||
for (int i = 0; i < n_vars; i++)
|
||||
{
|
||||
GtkCssSection *section;
|
||||
|
||||
if (names[i + 1])
|
||||
g_set_error (&new_error,
|
||||
GTK_CSS_PARSER_ERROR, GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE,
|
||||
error->domain, error->code,
|
||||
"While expanding %s: %s", names[i + 1], error->message);
|
||||
else
|
||||
g_set_error_literal (&new_error,
|
||||
GTK_CSS_PARSER_ERROR, GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE,
|
||||
error->domain, error->code,
|
||||
error->message);
|
||||
gtk_style_provider_emit_error (provider, vars[i]->section, new_error);
|
||||
|
||||
if (vars[i]->section == NULL)
|
||||
section = gtk_css_section_new (gtk_css_parser_get_file (parser), start, end);
|
||||
else
|
||||
section = gtk_css_section_ref (vars[i]->section);
|
||||
|
||||
gtk_style_provider_emit_error (provider, section, new_error);
|
||||
|
||||
gtk_css_section_unref (section);
|
||||
g_clear_error (&new_error);
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user