Compare commits
51 Commits
async-colo
...
matthiasc/
Author | SHA1 | Date | |
---|---|---|---|
|
6cb3300009 | ||
|
fde2fefbcd | ||
|
b6eb23afa7 | ||
|
17b7e9819b | ||
|
966a150d19 | ||
|
1b83c44994 | ||
|
6e75db713c | ||
|
82b45004c2 | ||
|
31b9e8dca6 | ||
|
623cdaf485 | ||
|
77280d258a | ||
|
80bf2336c9 | ||
|
55179c450b | ||
|
f7268a5c52 | ||
|
0e0bb92ff9 | ||
|
616a9e1804 | ||
|
7371840772 | ||
|
ca062df561 | ||
|
b09c642c98 | ||
|
830892e1b7 | ||
|
fda050e4fa | ||
|
7e91c156fe | ||
|
d9e6e92a64 | ||
|
ff78a913d7 | ||
|
91ffa97874 | ||
|
3ce7556235 | ||
|
2880a9c80f | ||
|
f0e2e58939 | ||
|
4137f26f41 | ||
|
b4116cbbb2 | ||
|
c5909b16ad | ||
|
d2f9acf3b0 | ||
|
3214e5a703 | ||
|
9ceaf3445d | ||
|
8fd866ba2e | ||
|
f1e3ccf0d4 | ||
|
03c9e25377 | ||
|
d161830d4c | ||
|
d546785f90 | ||
|
e9315dbcf8 | ||
|
69403eb66c | ||
|
23fdeb9f20 | ||
|
157ad464d8 | ||
|
e675b54df7 | ||
|
9b824abddd | ||
|
28f670d5fa | ||
|
28d70d17e0 | ||
|
b286901f2b | ||
|
588a7212c7 | ||
|
6979811b0e | ||
|
87fcac7508 |
@@ -192,7 +192,6 @@ macos:
|
||||
only:
|
||||
- branches@GNOME/gtk
|
||||
stage: build
|
||||
allow_failure: true
|
||||
tags:
|
||||
- macos
|
||||
needs: []
|
||||
|
@@ -42,6 +42,7 @@ RUN dnf -y install \
|
||||
iso-codes \
|
||||
itstool \
|
||||
json-glib-devel \
|
||||
lcms2-devel \
|
||||
lcov \
|
||||
libasan \
|
||||
libattr-devel \
|
||||
@@ -71,6 +72,7 @@ RUN dnf -y install \
|
||||
mesa-libEGL-devel \
|
||||
mesa-libGLES-devel \
|
||||
meson \
|
||||
mutter \
|
||||
ninja-build \
|
||||
pango-devel \
|
||||
pcre-devel \
|
||||
|
@@ -33,6 +33,10 @@ pacman --noconfirm -S --needed \
|
||||
mingw-w64-$MSYS2_ARCH-gst-plugins-bad-libs \
|
||||
mingw-w64-$MSYS2_ARCH-shared-mime-info \
|
||||
mingw-w64-$MSYS2_ARCH-python-gobject
|
||||
mingw-w64-$MSYS2_ARCH-libpng \
|
||||
mingw-w64-$MSYS2_ARCH-libjpeg-turbo \
|
||||
mingw-w64-$MSYS2_ARCH-libtiff \
|
||||
mingw-w64-$MSYS2_ARCH-lcms2
|
||||
|
||||
mkdir -p _ccache
|
||||
export CCACHE_BASEDIR="$(pwd)"
|
||||
|
43
NEWS
@@ -1,49 +1,6 @@
|
||||
Overview of Changes in 4.9.1, dd-mm-yyyy
|
||||
========================================
|
||||
|
||||
Note that deprecations are an early outlook
|
||||
at changes that will appear in an eventual
|
||||
GTK 5 release, which is still far away.
|
||||
|
||||
* GtkTreeView, GtkIconView, GtkComboBox and
|
||||
auxiliary classes have been deprecated
|
||||
|
||||
* GtkEntryCompletion has been deprecated
|
||||
|
||||
* GtkStyleContext has been deprecated
|
||||
|
||||
* gtk_render_ and gtk_snapshot_render_ APIs
|
||||
have been deprecated
|
||||
|
||||
* GtkAppChooser widgets hae been deprecated
|
||||
|
||||
* GtkMountOperation:
|
||||
- Fix the dialog to look reasonable
|
||||
- Make it work under non-X11
|
||||
|
||||
* GtkStringSorter:
|
||||
- Support different collation methods
|
||||
|
||||
* Accessibility:
|
||||
- Introduce GtkAccessibleRange and implement it
|
||||
|
||||
* Debugging:
|
||||
- Unify formatting for debug output
|
||||
- Make make debug options available in
|
||||
non-debug builds
|
||||
|
||||
* Translation updates:
|
||||
Abkhazian
|
||||
Basque
|
||||
Bulgarian
|
||||
Croatian
|
||||
Friulian
|
||||
Georgian
|
||||
German
|
||||
Hungarian
|
||||
Russian
|
||||
Turkish
|
||||
|
||||
|
||||
Overview of Changes in 4.8.1, 16-09-2022
|
||||
========================================
|
||||
|
@@ -21,8 +21,6 @@
|
||||
|
||||
#include "constraint-editor.h"
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
struct _ConstraintEditor
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
@@ -21,8 +21,6 @@
|
||||
|
||||
#include "guide-editor.h"
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
struct _GuideEditor
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
After Width: | Height: | Size: 24 KiB |
BIN
demos/gtk-demo/ICC-Rendering-Intent-Test.jpg
Normal file
After Width: | Height: | Size: 290 KiB |
BIN
demos/gtk-demo/ICC-Rendering-Intent-Test.png
Normal file
After Width: | Height: | Size: 120 KiB |
BIN
demos/gtk-demo/ICC-Rendering-Intent-Test.tif
Normal file
86
demos/gtk-demo/colorspaces.c
Normal file
@@ -0,0 +1,86 @@
|
||||
/* Color Spaces
|
||||
*
|
||||
* Demonstrates support for color spaces.
|
||||
*
|
||||
* The test images used here are taken from http://displaycal.net/icc-color-management-test/
|
||||
* and are licensed under the Creative Commons BY-SA 4.0 International License
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static GtkWidget *jpeg;
|
||||
static GtkWidget *png;
|
||||
static GtkWidget *tiff;
|
||||
static GtkWidget *noprofile;
|
||||
static GtkWidget *test1;
|
||||
static GtkWidget *test2;
|
||||
|
||||
static void
|
||||
on_changed (GtkCheckButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkTexture *texture;
|
||||
const char *extension = NULL;
|
||||
char *path;
|
||||
|
||||
if (!gtk_check_button_get_active (GTK_CHECK_BUTTON (button)))
|
||||
return;
|
||||
|
||||
if (gtk_check_button_get_active (GTK_CHECK_BUTTON (jpeg)))
|
||||
extension = ".jpg";
|
||||
else if (gtk_check_button_get_active (GTK_CHECK_BUTTON (png)))
|
||||
extension = ".png";
|
||||
else if (gtk_check_button_get_active (GTK_CHECK_BUTTON (tiff)))
|
||||
extension = ".tif";
|
||||
else if (gtk_check_button_get_active (GTK_CHECK_BUTTON (noprofile)))
|
||||
extension = "-expected-result-no-cm.png";
|
||||
|
||||
path = g_strconcat ("/colorspaces/sRGB_Gray", extension, NULL);
|
||||
texture = gdk_texture_new_from_resource (path);
|
||||
gtk_picture_set_paintable (GTK_PICTURE (test1), GDK_PAINTABLE (texture));
|
||||
g_object_unref (texture);
|
||||
|
||||
path = g_strconcat ("/colorspaces/ICC-Rendering-Intent-Test", extension, NULL);
|
||||
texture = gdk_texture_new_from_resource (path);
|
||||
gtk_picture_set_paintable (GTK_PICTURE (test2), GDK_PAINTABLE (texture));
|
||||
g_object_unref (texture);
|
||||
}
|
||||
|
||||
GtkWidget*
|
||||
do_colorspaces (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
GtkBuilderScope *scope;
|
||||
|
||||
scope = gtk_builder_cscope_new ();
|
||||
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope),
|
||||
"on_changed", G_CALLBACK (on_changed));
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_set_scope (builder, scope);
|
||||
gtk_builder_add_from_resource (builder, "/colorspaces/colorspaces.ui", NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
jpeg = GTK_WIDGET (gtk_builder_get_object (builder, "jpeg"));
|
||||
png = GTK_WIDGET (gtk_builder_get_object (builder, "png"));
|
||||
tiff = GTK_WIDGET (gtk_builder_get_object (builder, "tiff"));
|
||||
noprofile = GTK_WIDGET (gtk_builder_get_object (builder, "noprofile"));
|
||||
test1 = GTK_WIDGET (gtk_builder_get_object (builder, "test1"));
|
||||
test2 = GTK_WIDGET (gtk_builder_get_object (builder, "test2"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
g_object_unref (builder);
|
||||
g_object_unref (scope);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
|
||||
return window;
|
||||
}
|
94
demos/gtk-demo/colorspaces.ui
Normal file
@@ -0,0 +1,94 @@
|
||||
<interface>
|
||||
<object class="GtkWindow" id="window">
|
||||
<property name="default-width">660</property>
|
||||
<property name="default-height">660</property>
|
||||
<property name="resizable">false</property>
|
||||
<property name="title">Color Profiles</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">10</property>
|
||||
<property name="margin-top">10</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">File format:</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="jpeg">
|
||||
<property name="label">JPEG</property>
|
||||
<property name="active">1</property>
|
||||
<signal name="notify::active" handler="on_changed"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="png">
|
||||
<property name="label">PNG</property>
|
||||
<property name="group">jpeg</property>
|
||||
<signal name="notify::active" handler="on_changed"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="tiff">
|
||||
<property name="label">TIFF</property>
|
||||
<property name="group">png</property>
|
||||
<signal name="notify::active" handler="on_changed"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="noprofile">
|
||||
<property name="label">No profile</property>
|
||||
<property name="group">tiff</property>
|
||||
<signal name="notify::active" handler="on_changed"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Test 1: Matrix-based profile</property>
|
||||
<style>
|
||||
<class name="title-3"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkPicture" id="test1">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<property name="can-shrink">1</property>
|
||||
<property name="keep-aspect-ratio">1</property>
|
||||
<property name="file">resource:///colorprofiles/sRGB_Gray.jpg</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Test 2: Lookup table-based profile</property>
|
||||
<style>
|
||||
<class name="title-3"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkPicture" id="test2">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<property name="can-shrink">1</property>
|
||||
<property name="keep-aspect-ratio">1</property>
|
||||
<property name="file">resource:///colorprofiles/ICC-Rendering-Intent-Test.jpg</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
@@ -11,8 +11,6 @@
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
enum
|
||||
{
|
||||
ICON_NAME_COL,
|
||||
|
@@ -1,16 +1,20 @@
|
||||
/* Theming/CSS Accordion
|
||||
*
|
||||
* A simple accordion demo written using CSS transitions and multiple backgrounds
|
||||
*
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static void
|
||||
destroy_provider (GtkWidget *window,
|
||||
GtkStyleProvider *provider)
|
||||
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
||||
{
|
||||
gtk_style_context_remove_provider_for_display (gtk_widget_get_display (window), provider);
|
||||
GtkWidget *child;
|
||||
|
||||
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
apply_css (child, provider);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
@@ -20,8 +24,8 @@ do_css_accordion (GtkWidget *do_widget)
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *container, *styled_box, *child;
|
||||
GtkCssProvider *provider;
|
||||
GtkWidget *container, *child;
|
||||
GtkStyleProvider *provider;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_title (GTK_WINDOW (window), "CSS Accordion");
|
||||
@@ -29,13 +33,10 @@ do_css_accordion (GtkWidget *do_widget)
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 300);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
styled_box = gtk_frame_new (NULL);
|
||||
gtk_window_set_child (GTK_WINDOW (window), styled_box);
|
||||
gtk_widget_add_css_class (styled_box, "accordion");
|
||||
container = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_widget_set_halign (container, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (container, GTK_ALIGN_CENTER);
|
||||
gtk_frame_set_child (GTK_FRAME (styled_box), container);
|
||||
gtk_window_set_child (GTK_WINDOW (window), container);
|
||||
|
||||
child = gtk_button_new_with_label ("This");
|
||||
gtk_box_append (GTK_BOX (container), child);
|
||||
@@ -55,16 +56,10 @@ do_css_accordion (GtkWidget *do_widget)
|
||||
child = gtk_button_new_with_label (":-)");
|
||||
gtk_box_append (GTK_BOX (container), child);
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (provider, "/css_accordion/css_accordion.css");
|
||||
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||
gtk_css_provider_load_from_resource (GTK_CSS_PROVIDER (provider), "/css_accordion/css_accordion.css");
|
||||
|
||||
gtk_style_context_add_provider_for_display (gtk_widget_get_display (window),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (destroy_provider), provider);
|
||||
g_object_unref (provider);
|
||||
apply_css (window, provider);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
@@ -1,13 +1,13 @@
|
||||
.accordion, .accordion * {
|
||||
all: unset;
|
||||
@import url("resource://css_accordion/reset.css");
|
||||
|
||||
* {
|
||||
transition-property: color, background-color, border-color, background-image, padding, border-width;
|
||||
transition-duration: 1s;
|
||||
|
||||
font: 20px Cantarell;
|
||||
}
|
||||
|
||||
.accordion {
|
||||
window {
|
||||
background: linear-gradient(153deg, #151515, #151515 5px, transparent 5px) 0 0,
|
||||
linear-gradient(333deg, #151515, #151515 5px, transparent 5px) 10px 5px,
|
||||
linear-gradient(153deg, #222, #222 5px, transparent 5px) 0 5px,
|
||||
@@ -18,7 +18,7 @@
|
||||
background-size: 20px 20px;
|
||||
}
|
||||
|
||||
.accordion button {
|
||||
button {
|
||||
color: black;
|
||||
background-color: #bbb;
|
||||
border-style: solid;
|
||||
@@ -28,25 +28,25 @@
|
||||
padding: 12px 4px;
|
||||
}
|
||||
|
||||
.accordion button:first-child {
|
||||
button:first-child {
|
||||
border-radius: 5px 0 0 5px;
|
||||
}
|
||||
|
||||
.accordion button:last-child {
|
||||
button:last-child {
|
||||
border-radius: 0 5px 5px 0;
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.accordion button:hover {
|
||||
button:hover {
|
||||
padding: 12px 48px;
|
||||
background-color: #4870bc;
|
||||
}
|
||||
|
||||
.accordion button *:hover {
|
||||
button *:hover {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.accordion button:hover:active,
|
||||
.accordion button:active {
|
||||
button:hover:active,
|
||||
button:active {
|
||||
background-color: #993401;
|
||||
}
|
||||
|
@@ -6,8 +6,6 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static void
|
||||
show_parsing_error (GtkCssProvider *provider,
|
||||
GtkCssSection *section,
|
||||
|
@@ -6,8 +6,6 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static void
|
||||
show_parsing_error (GtkCssProvider *provider,
|
||||
GtkCssSection *section,
|
||||
|
@@ -7,8 +7,6 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static void
|
||||
show_parsing_error (GtkCssProvider *provider,
|
||||
GtkCssSection *section,
|
||||
|
@@ -5,8 +5,6 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static void
|
||||
show_parsing_error (GtkCssProvider *provider,
|
||||
GtkCssSection *section,
|
||||
|
@@ -19,11 +19,23 @@
|
||||
<file>demoimage.c</file>
|
||||
<file>demoimage.h</file>
|
||||
</gresource>
|
||||
<gresource prefix="/colorspaces">
|
||||
<file>colorspaces.ui</file>
|
||||
<file>sRGB_Gray.jpg</file>
|
||||
<file>sRGB_Gray.png</file>
|
||||
<file>sRGB_Gray.tif</file>
|
||||
<file>sRGB_Gray-expected-result-no-cm.png</file>
|
||||
<file>ICC-Rendering-Intent-Test.png</file>
|
||||
<file>ICC-Rendering-Intent-Test.jpg</file>
|
||||
<file>ICC-Rendering-Intent-Test.tif</file>
|
||||
<file>ICC-Rendering-Intent-Test-expected-result-no-cm.png</file>
|
||||
</gresource>
|
||||
<gresource prefix="/constraints_builder">
|
||||
<file>constraints_builder.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/css_accordion">
|
||||
<file>css_accordion.css</file>
|
||||
<file>reset.css</file>
|
||||
</gresource>
|
||||
<gresource prefix="/css_basics">
|
||||
<file>css_basics.css</file>
|
||||
@@ -254,6 +266,7 @@
|
||||
<file>assistant.c</file>
|
||||
<file>builder.c</file>
|
||||
<file>clipboard.c</file>
|
||||
<file>colorspaces.c</file>
|
||||
<file>combobox.c</file>
|
||||
<file>constraints.c</file>
|
||||
<file>constraints_interactive.c</file>
|
||||
|
@@ -11,7 +11,6 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
G_DECLARE_FINAL_TYPE (CanvasItem, canvas_item, CANVAS, ITEM, GtkWidget)
|
||||
|
||||
struct _CanvasItem {
|
||||
@@ -25,9 +24,6 @@ struct _CanvasItem {
|
||||
double delta;
|
||||
|
||||
GtkWidget *editor;
|
||||
|
||||
GtkStyleProvider *provider;
|
||||
char *css_class;
|
||||
};
|
||||
|
||||
struct _CanvasItemClass {
|
||||
@@ -38,41 +34,32 @@ G_DEFINE_TYPE (CanvasItem, canvas_item, GTK_TYPE_WIDGET)
|
||||
|
||||
static int n_items = 0;
|
||||
|
||||
static void
|
||||
unstyle_item (CanvasItem *item)
|
||||
{
|
||||
if (item->provider)
|
||||
{
|
||||
gtk_style_context_remove_provider_for_display (gtk_widget_get_display (item->label), item->provider);
|
||||
g_clear_object (&item->provider);
|
||||
}
|
||||
|
||||
if (item->css_class)
|
||||
{
|
||||
gtk_widget_remove_css_class (item->label, item->css_class);
|
||||
g_clear_pointer (&item->css_class, g_free);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_color (CanvasItem *item,
|
||||
GdkRGBA *color)
|
||||
{
|
||||
char *css;
|
||||
char *str;
|
||||
GtkStyleContext *context;
|
||||
GtkCssProvider *provider;
|
||||
const char *name;
|
||||
|
||||
unstyle_item (item);
|
||||
const char *old_class;
|
||||
|
||||
str = gdk_rgba_to_string (color);
|
||||
name = gtk_widget_get_name (item->label);
|
||||
css = g_strdup_printf ("#%s { background: %s; }", name, str);
|
||||
css = g_strdup_printf ("* { background: %s; }", str);
|
||||
|
||||
context = gtk_widget_get_style_context (item->label);
|
||||
provider = g_object_get_data (G_OBJECT (context), "style-provider");
|
||||
if (provider)
|
||||
gtk_style_context_remove_provider (context, GTK_STYLE_PROVIDER (provider));
|
||||
|
||||
old_class = (const char *)g_object_get_data (G_OBJECT (item->label), "css-class");
|
||||
if (old_class)
|
||||
gtk_widget_remove_css_class (item->label, old_class);
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_data (provider, css, -1);
|
||||
gtk_style_context_add_provider_for_display (gtk_widget_get_display (item->label), GTK_STYLE_PROVIDER (provider), 700);
|
||||
item->provider = GTK_STYLE_PROVIDER (provider);
|
||||
gtk_style_context_add_provider (gtk_widget_get_style_context (item->label), GTK_STYLE_PROVIDER (provider), 800);
|
||||
g_object_set_data_full (G_OBJECT (context), "style-provider", provider, g_object_unref);
|
||||
|
||||
g_free (str);
|
||||
g_free (css);
|
||||
@@ -82,10 +69,21 @@ static void
|
||||
set_css (CanvasItem *item,
|
||||
const char *class)
|
||||
{
|
||||
unstyle_item (item);
|
||||
GtkStyleContext *context;
|
||||
GtkCssProvider *provider;
|
||||
const char *old_class;
|
||||
|
||||
context = gtk_widget_get_style_context (item->label);
|
||||
provider = g_object_get_data (G_OBJECT (context), "style-provider");
|
||||
if (provider)
|
||||
gtk_style_context_remove_provider (context, GTK_STYLE_PROVIDER (provider));
|
||||
|
||||
old_class = (const char *)g_object_get_data (G_OBJECT (item->label), "css-class");
|
||||
if (old_class)
|
||||
gtk_widget_remove_css_class (item->label, old_class);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (item->label), "css-class", g_strdup (class), g_free);
|
||||
gtk_widget_add_css_class (item->label, class);
|
||||
item->css_class = g_strdup (class);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -724,7 +722,6 @@ do_dnd (GtkWidget *do_widget)
|
||||
int i;
|
||||
int x, y;
|
||||
GtkCssProvider *provider;
|
||||
GString *css;
|
||||
|
||||
button = gtk_color_button_new ();
|
||||
g_object_unref (g_object_ref_sink (button));
|
||||
@@ -736,18 +733,6 @@ do_dnd (GtkWidget *do_widget)
|
||||
800);
|
||||
g_object_unref (provider);
|
||||
|
||||
css = g_string_new ("");
|
||||
for (i = 0; colors[i]; i++)
|
||||
g_string_append_printf (css, ".canvasitem.%s { background: %s; }\n", colors[i], colors[i]);
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_data (provider, css->str, css->len);
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
800);
|
||||
g_object_unref (provider);
|
||||
g_string_free (css, TRUE);
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
|
@@ -14,8 +14,6 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int number;
|
||||
|
@@ -8,8 +8,6 @@
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
/* Creates a tree model containing the completions */
|
||||
static GtkTreeModel *
|
||||
create_completion_model (void)
|
||||
|
@@ -9,8 +9,6 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
enum {
|
||||
WIDTH_COLUMN,
|
||||
HEIGHT_COLUMN,
|
||||
|
@@ -21,75 +21,6 @@
|
||||
#include "script-names.h"
|
||||
#include "language-names.h"
|
||||
|
||||
/* {{{ ScriptLang object */
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ScriptLang, script_lang, SCRIPT, LANG, GObject)
|
||||
|
||||
struct _ScriptLang
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
char *langname;
|
||||
unsigned int script_index;
|
||||
unsigned int lang_index;
|
||||
hb_tag_t lang_tag;
|
||||
};
|
||||
|
||||
struct _ScriptLangClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ScriptLang, script_lang, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
script_lang_init (ScriptLang *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
script_lang_finalize (GObject *object)
|
||||
{
|
||||
ScriptLang *self = SCRIPT_LANG (object);
|
||||
|
||||
g_free (self->langname);
|
||||
|
||||
G_OBJECT_CLASS (script_lang_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
script_lang_class_init (ScriptLangClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->finalize = script_lang_finalize;
|
||||
}
|
||||
|
||||
static ScriptLang *
|
||||
script_lang_new (const char *langname,
|
||||
unsigned int script_index,
|
||||
unsigned int lang_index,
|
||||
hb_tag_t lang_tag)
|
||||
{
|
||||
ScriptLang *self;
|
||||
|
||||
self = g_object_new (script_lang_get_type (), NULL);
|
||||
|
||||
self->langname = g_strdup (langname);
|
||||
self->script_index = script_index;
|
||||
self->lang_index = lang_index;
|
||||
self->lang_tag = lang_tag;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static char *
|
||||
script_lang_get_langname (ScriptLang *self)
|
||||
{
|
||||
return g_strdup (self->langname);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
#define MAKE_TAG(a,b,c,d) (unsigned int)(((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
|
||||
|
||||
@@ -163,10 +94,6 @@ demo_free (gpointer data)
|
||||
g_clear_pointer (&demo->axes, g_hash_table_unref);
|
||||
g_clear_pointer (&demo->text, g_free);
|
||||
|
||||
gtk_style_context_remove_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (demo->provider));
|
||||
g_object_unref (demo->provider);
|
||||
|
||||
g_free (demo);
|
||||
}
|
||||
|
||||
@@ -544,6 +471,8 @@ update_display (void)
|
||||
GString *s;
|
||||
char *text;
|
||||
gboolean has_feature;
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel *model;
|
||||
PangoFontDescription *desc;
|
||||
GList *l;
|
||||
PangoAttrList *attrs;
|
||||
@@ -646,13 +575,14 @@ update_display (void)
|
||||
|
||||
features = g_string_free (s, FALSE);
|
||||
|
||||
if (gtk_drop_down_get_selected (GTK_DROP_DOWN (demo->script_lang)) != 0)
|
||||
if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (demo->script_lang), &iter))
|
||||
{
|
||||
ScriptLang *selected;
|
||||
hb_tag_t lang_tag;
|
||||
|
||||
selected = gtk_drop_down_get_selected_item (GTK_DROP_DOWN (demo->script_lang));
|
||||
model = gtk_combo_box_get_model (GTK_COMBO_BOX (demo->script_lang));
|
||||
gtk_tree_model_get (model, &iter, 3, &lang_tag, -1);
|
||||
|
||||
lang = pango_language_from_string (hb_language_to_string (hb_ot_tag_to_language (selected->lang_tag)));
|
||||
lang = pango_language_from_string (hb_language_to_string (hb_ot_tag_to_language (lang_tag)));
|
||||
}
|
||||
else
|
||||
lang = NULL;
|
||||
@@ -809,30 +739,40 @@ tag_pair_equal (gconstpointer a, gconstpointer b)
|
||||
return pair_a->script_tag == pair_b->script_tag && pair_a->lang_tag == pair_b->lang_tag;
|
||||
}
|
||||
|
||||
|
||||
static GtkOrdering
|
||||
script_sort (const void *item1,
|
||||
const void *item2,
|
||||
void *data)
|
||||
static int
|
||||
script_sort_func (GtkTreeModel *model,
|
||||
GtkTreeIter *a,
|
||||
GtkTreeIter *b,
|
||||
gpointer user_data)
|
||||
{
|
||||
ScriptLang *a = (ScriptLang *)item1;
|
||||
ScriptLang *b = (ScriptLang *)item2;
|
||||
char *sa, *sb;
|
||||
int ret;
|
||||
|
||||
return strcmp (a->langname, b->langname);
|
||||
gtk_tree_model_get (model, a, 0, &sa, -1);
|
||||
gtk_tree_model_get (model, b, 0, &sb, -1);
|
||||
|
||||
ret = strcmp (sa, sb);
|
||||
|
||||
g_free (sa);
|
||||
g_free (sb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
update_script_combo (void)
|
||||
{
|
||||
GListStore *store;
|
||||
GtkSortListModel *sortmodel;
|
||||
GtkListStore *store;
|
||||
hb_font_t *hb_font;
|
||||
int i, j, k;
|
||||
PangoFont *pango_font;
|
||||
GHashTable *tags;
|
||||
GHashTableIter iter;
|
||||
TagPair *pair;
|
||||
char *lang;
|
||||
hb_tag_t active;
|
||||
GtkTreeIter active_iter;
|
||||
gboolean have_active = FALSE;
|
||||
|
||||
lang = gtk_font_chooser_get_language (GTK_FONT_CHOOSER (demo->font));
|
||||
|
||||
@@ -842,7 +782,7 @@ update_script_combo (void)
|
||||
|
||||
g_free (lang);
|
||||
|
||||
store = g_list_store_new (script_lang_get_type ());
|
||||
store = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
|
||||
|
||||
pango_font = get_pango_font ();
|
||||
hb_font = pango_font_get_hb_font (pango_font);
|
||||
@@ -866,19 +806,19 @@ update_script_combo (void)
|
||||
|
||||
hb_face = hb_font_get_face (hb_font);
|
||||
|
||||
for (guint i = 0; i < 2; i++)
|
||||
for (i= 0; i < 2; i++)
|
||||
{
|
||||
hb_tag_t scripts[80];
|
||||
unsigned int script_count = G_N_ELEMENTS (scripts);
|
||||
|
||||
hb_ot_layout_table_get_script_tags (hb_face, tables[i], 0, &script_count, scripts);
|
||||
for (guint j = 0; j < script_count; j++)
|
||||
for (j = 0; j < script_count; j++)
|
||||
{
|
||||
hb_tag_t languages[80];
|
||||
unsigned int language_count = G_N_ELEMENTS (languages);
|
||||
|
||||
hb_ot_layout_script_get_language_tags (hb_face, tables[i], j, 0, &language_count, languages);
|
||||
for (guint k = 0; k < language_count; k++)
|
||||
for (k = 0; k < language_count; k++)
|
||||
{
|
||||
pair = g_new (TagPair, 1);
|
||||
pair->script_tag = scripts[j];
|
||||
@@ -898,6 +838,7 @@ update_script_combo (void)
|
||||
{
|
||||
const char *langname;
|
||||
char langbuf[5];
|
||||
GtkTreeIter tree_iter;
|
||||
|
||||
if (pair->lang_tag == 0 && pair->script_tag == 0)
|
||||
langname = NC_("Language", "None");
|
||||
@@ -914,31 +855,31 @@ update_script_combo (void)
|
||||
}
|
||||
}
|
||||
|
||||
g_list_store_append (store, script_lang_new (langname,
|
||||
pair->script_index,
|
||||
pair->lang_index,
|
||||
pair->lang_tag));
|
||||
gtk_list_store_insert_with_values (store, &tree_iter, -1,
|
||||
0, langname,
|
||||
1, pair->script_index,
|
||||
2, pair->lang_index,
|
||||
3, pair->lang_tag,
|
||||
-1);
|
||||
if (pair->lang_tag == active)
|
||||
{
|
||||
have_active = TRUE;
|
||||
active_iter = tree_iter;
|
||||
}
|
||||
}
|
||||
|
||||
g_hash_table_destroy (tags);
|
||||
|
||||
sortmodel = gtk_sort_list_model_new (G_LIST_MODEL (store),
|
||||
GTK_SORTER (gtk_custom_sorter_new (script_sort, NULL, NULL)));
|
||||
gtk_drop_down_set_model (GTK_DROP_DOWN (demo->script_lang), G_LIST_MODEL (sortmodel));
|
||||
|
||||
for (guint i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (sortmodel)); i++)
|
||||
{
|
||||
ScriptLang *item = g_list_model_get_item (G_LIST_MODEL (sortmodel), i);
|
||||
g_object_unref (item);
|
||||
|
||||
if (item->lang_tag == active)
|
||||
{
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (demo->script_lang), i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (sortmodel);
|
||||
gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (store),
|
||||
script_sort_func, NULL, NULL);
|
||||
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
|
||||
GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
|
||||
GTK_SORT_ASCENDING);
|
||||
gtk_combo_box_set_model (GTK_COMBO_BOX (demo->script_lang), GTK_TREE_MODEL (store));
|
||||
if (have_active)
|
||||
gtk_combo_box_set_active_iter (GTK_COMBO_BOX (demo->script_lang), &active_iter);
|
||||
else
|
||||
gtk_combo_box_set_active_iter (GTK_COMBO_BOX (demo->script_lang), 0);
|
||||
}
|
||||
|
||||
static char *
|
||||
@@ -963,19 +904,27 @@ static void
|
||||
update_features (void)
|
||||
{
|
||||
int i, j;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
guint script_index, lang_index;
|
||||
hb_tag_t lang_tag;
|
||||
PangoFont *pango_font;
|
||||
hb_font_t *hb_font;
|
||||
GList *l;
|
||||
ScriptLang *selected;
|
||||
|
||||
/* set feature presence checks from the font features */
|
||||
|
||||
if (gtk_drop_down_get_selected (GTK_DROP_DOWN (demo->script_lang)) == 0)
|
||||
if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (demo->script_lang), &iter))
|
||||
return;
|
||||
|
||||
selected = gtk_drop_down_get_selected_item (GTK_DROP_DOWN (demo->script_lang));
|
||||
model = gtk_combo_box_get_model (GTK_COMBO_BOX (demo->script_lang));
|
||||
gtk_tree_model_get (model, &iter,
|
||||
1, &script_index,
|
||||
2, &lang_index,
|
||||
3, &lang_tag,
|
||||
-1);
|
||||
|
||||
if (selected->lang_tag == 0) /* None is selected */
|
||||
if (lang_tag == 0) /* None is selected */
|
||||
{
|
||||
for (l = demo->feature_items; l; l = l->next)
|
||||
{
|
||||
@@ -1016,8 +965,8 @@ update_features (void)
|
||||
|
||||
hb_ot_layout_language_get_feature_tags (hb_face,
|
||||
tables[i],
|
||||
selected->script_index,
|
||||
selected->lang_index,
|
||||
script_index,
|
||||
lang_index,
|
||||
0,
|
||||
&count,
|
||||
features);
|
||||
@@ -1039,8 +988,8 @@ update_features (void)
|
||||
|
||||
hb_ot_layout_language_find_feature (hb_face,
|
||||
tables[i],
|
||||
selected->script_index,
|
||||
selected->lang_index,
|
||||
script_index,
|
||||
lang_index,
|
||||
features[j],
|
||||
&feature_index);
|
||||
|
||||
@@ -1372,9 +1321,10 @@ free_instance (gpointer data)
|
||||
}
|
||||
|
||||
static void
|
||||
add_instance (hb_face_t *face,
|
||||
unsigned int index,
|
||||
GtkStringList *strings)
|
||||
add_instance (hb_face_t *face,
|
||||
unsigned int index,
|
||||
GtkWidget *combo,
|
||||
int pos)
|
||||
{
|
||||
Instance *instance;
|
||||
hb_ot_name_id_t name_id;
|
||||
@@ -1390,20 +1340,20 @@ add_instance (hb_face_t *face,
|
||||
instance->index = index;
|
||||
|
||||
g_hash_table_add (demo->instances, instance);
|
||||
gtk_string_list_append (GTK_STRING_LIST (strings), instance->name);
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), instance->name);
|
||||
}
|
||||
|
||||
static void
|
||||
unset_instance (GtkAdjustment *adjustment)
|
||||
{
|
||||
if (demo->instance_combo)
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (demo->instance_combo), 0);
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (demo->instance_combo), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
instance_changed (GtkDropDown *combo)
|
||||
instance_changed (GtkComboBox *combo)
|
||||
{
|
||||
const char *text;
|
||||
char *text;
|
||||
Instance *instance;
|
||||
Instance ikey;
|
||||
int i;
|
||||
@@ -1415,12 +1365,11 @@ instance_changed (GtkDropDown *combo)
|
||||
hb_font_t *hb_font;
|
||||
hb_face_t *hb_face;
|
||||
|
||||
text = gtk_string_list_get_string (GTK_STRING_LIST (gtk_drop_down_get_model (combo)),
|
||||
gtk_drop_down_get_selected (combo));
|
||||
text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (combo));
|
||||
if (text[0] == '\0')
|
||||
goto out;
|
||||
|
||||
ikey.name = (char *) text;
|
||||
ikey.name = text;
|
||||
instance = g_hash_table_lookup (demo->instances, &ikey);
|
||||
if (!instance)
|
||||
{
|
||||
@@ -1461,6 +1410,7 @@ instance_changed (GtkDropDown *combo)
|
||||
}
|
||||
|
||||
out:
|
||||
g_free (text);
|
||||
g_clear_object (&pango_font);
|
||||
g_free (ai);
|
||||
g_free (coords);
|
||||
@@ -1570,7 +1520,6 @@ update_font_variations (void)
|
||||
{
|
||||
GtkWidget *label;
|
||||
GtkWidget *combo;
|
||||
GtkStringList *strings;
|
||||
|
||||
label = gtk_label_new ("Instance");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
@@ -1578,28 +1527,26 @@ update_font_variations (void)
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
|
||||
gtk_grid_attach (GTK_GRID (demo->variations_grid), label, 0, -1, 1, 1);
|
||||
|
||||
strings = gtk_string_list_new (NULL);
|
||||
combo = gtk_drop_down_new (G_LIST_MODEL (strings), NULL);
|
||||
|
||||
combo = gtk_combo_box_text_new ();
|
||||
gtk_widget_set_halign (combo, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (combo, GTK_ALIGN_BASELINE);
|
||||
|
||||
gtk_string_list_append (strings, "");
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "");
|
||||
|
||||
for (i = 0; i < hb_ot_var_get_named_instance_count (hb_face); i++)
|
||||
add_instance (hb_face, i, strings);
|
||||
add_instance (hb_face, i, combo, i);
|
||||
|
||||
for (i = 0; i < hb_ot_var_get_named_instance_count (hb_face); i++)
|
||||
{
|
||||
if (matches_instance (hb_face, i, n_axes, design_coords))
|
||||
{
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (combo), i + 1);
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), i + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gtk_grid_attach (GTK_GRID (demo->variations_grid), combo, 1, -1, 3, 1);
|
||||
g_signal_connect (combo, "notify::selecte", G_CALLBACK (instance_changed), NULL);
|
||||
g_signal_connect (combo, "changed", G_CALLBACK (instance_changed), NULL);
|
||||
demo->instance_combo = combo;
|
||||
}
|
||||
|
||||
@@ -1746,7 +1693,6 @@ do_font_features (GtkWidget *do_widget)
|
||||
GtkBuilder *builder;
|
||||
GtkBuilderScope *scope;
|
||||
GtkEventController *controller;
|
||||
GtkExpression *expression;
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
|
||||
@@ -1780,9 +1726,6 @@ do_font_features (GtkWidget *do_widget)
|
||||
demo->description = GTK_WIDGET (gtk_builder_get_object (builder, "description"));
|
||||
demo->font = GTK_WIDGET (gtk_builder_get_object (builder, "font"));
|
||||
demo->script_lang = GTK_WIDGET (gtk_builder_get_object (builder, "script_lang"));
|
||||
expression = gtk_cclosure_expression_new (G_TYPE_STRING, NULL, 0, NULL, G_CALLBACK (script_lang_get_langname), NULL, NULL);
|
||||
gtk_drop_down_set_expression (GTK_DROP_DOWN (demo->script_lang), expression);
|
||||
gtk_expression_unref (expression);
|
||||
demo->feature_list = GTK_WIDGET (gtk_builder_get_object (builder, "feature_list"));
|
||||
demo->stack = GTK_WIDGET (gtk_builder_get_object (builder, "stack"));
|
||||
demo->entry = GTK_WIDGET (gtk_builder_get_object (builder, "entry"));
|
||||
@@ -1801,8 +1744,8 @@ do_font_features (GtkWidget *do_widget)
|
||||
demo->swin = GTK_WIDGET (gtk_builder_get_object (builder, "swin"));
|
||||
|
||||
demo->provider = gtk_css_provider_new ();
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (demo->provider), 800);
|
||||
gtk_style_context_add_provider (gtk_widget_get_style_context (demo->swin),
|
||||
GTK_STYLE_PROVIDER (demo->provider), 800);
|
||||
|
||||
basic_value_changed (demo->size_adjustment, demo->size_entry);
|
||||
basic_value_changed (demo->letterspacing_adjustment, demo->letterspacing_entry);
|
||||
@@ -1880,5 +1823,3 @@ do_font_features (GtkWidget *do_widget)
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
/* vim:set foldmethod=marker expandtab: */
|
||||
|
@@ -259,10 +259,16 @@
|
||||
<object class="GtkBox" id="feature_list">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkDropDown" id="script_lang">
|
||||
<object class="GtkComboBox" id="script_lang">
|
||||
<property name="tooltip-text" translatable="yes">Language System</property>
|
||||
<property name="margin-top">10</property>
|
||||
<signal name="notify::selected" handler="font_features_script_changed" swapped="no"/>
|
||||
<signal name="changed" handler="font_features_script_changed" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
@@ -43,6 +43,7 @@ update_image (void)
|
||||
cairo_t *cr;
|
||||
GdkPixbuf *pixbuf;
|
||||
GdkPixbuf *pixbuf2;
|
||||
const char *hint;
|
||||
cairo_font_options_t *fopt;
|
||||
cairo_hint_style_t hintstyle;
|
||||
cairo_hint_metrics_t hintmetrics;
|
||||
@@ -57,23 +58,18 @@ update_image (void)
|
||||
|
||||
fopt = cairo_font_options_copy (pango_cairo_context_get_font_options (context));
|
||||
|
||||
switch (gtk_drop_down_get_selected (GTK_DROP_DOWN (hinting)))
|
||||
hint = gtk_combo_box_get_active_id (GTK_COMBO_BOX (hinting));
|
||||
hintstyle = CAIRO_HINT_STYLE_DEFAULT;
|
||||
if (hint)
|
||||
{
|
||||
case 0:
|
||||
hintstyle = CAIRO_HINT_STYLE_NONE;
|
||||
break;
|
||||
case 1:
|
||||
hintstyle = CAIRO_HINT_STYLE_SLIGHT;
|
||||
break;
|
||||
case 2:
|
||||
hintstyle = CAIRO_HINT_STYLE_MEDIUM;
|
||||
break;
|
||||
case 3:
|
||||
hintstyle = CAIRO_HINT_STYLE_FULL;
|
||||
break;
|
||||
default:
|
||||
hintstyle = CAIRO_HINT_STYLE_DEFAULT;
|
||||
break;
|
||||
if (strcmp (hint, "none") == 0)
|
||||
hintstyle = CAIRO_HINT_STYLE_NONE;
|
||||
else if (strcmp (hint, "slight") == 0)
|
||||
hintstyle = CAIRO_HINT_STYLE_SLIGHT;
|
||||
else if (strcmp (hint, "medium") == 0)
|
||||
hintstyle = CAIRO_HINT_STYLE_MEDIUM;
|
||||
else if (strcmp (hint, "full") == 0)
|
||||
hintstyle = CAIRO_HINT_STYLE_FULL;
|
||||
}
|
||||
cairo_font_options_set_hint_style (fopt, hintstyle);
|
||||
|
||||
@@ -422,7 +418,7 @@ do_fontrendering (GtkWidget *do_widget)
|
||||
g_signal_connect (down_button, "clicked", G_CALLBACK (scale_down), NULL);
|
||||
g_signal_connect (entry, "notify::text", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (font_button, "notify::font-desc", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (hinting, "notify::selected", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (hinting, "notify::active", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (anti_alias, "notify::active", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (hint_metrics, "notify::active", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (text_radio, "notify::active", G_CALLBACK (update_image), NULL);
|
||||
|
@@ -116,18 +116,15 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropDown" id="hinting">
|
||||
<object class="GtkComboBoxText" id="hinting">
|
||||
<property name="active">0</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="model">
|
||||
<object class="GtkStringList">
|
||||
<items>
|
||||
<item translatable="yes">None</item>
|
||||
<item translatable="yes">Slight</item>
|
||||
<item translatable="yes">Medium</item>
|
||||
<item translatable="yes">Full</item>
|
||||
</items>
|
||||
</object>
|
||||
</property>
|
||||
<items>
|
||||
<item translatable="yes" id="none">None</item>
|
||||
<item translatable="yes" id="slight">Slight</item>
|
||||
<item translatable="yes" id="medium">Medium</item>
|
||||
<item translatable="yes" id="full">Full</item>
|
||||
</items>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
|
@@ -144,6 +144,7 @@ make_shader_stack (const char *name,
|
||||
GtkTextBuffer *buffer;
|
||||
GBytes *bytes;
|
||||
GtkEventController *controller;
|
||||
GtkCssProvider *provider;
|
||||
GdkPaintable *paintable;
|
||||
|
||||
stack = gtk_shader_stack_new ();
|
||||
@@ -234,6 +235,12 @@ make_shader_stack (const char *name,
|
||||
g_signal_connect (buffer, "changed", G_CALLBACK (text_changed), button);
|
||||
g_object_set_data (G_OBJECT (button), "the-stack", stack);
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (apply_text), buffer);
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_data (provider, "button.small { padding: 0; }", -1);
|
||||
gtk_style_context_add_provider (gtk_widget_get_style_context (button),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
g_object_unref (provider);
|
||||
gtk_widget_set_halign (button, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
|
||||
gtk_widget_add_css_class (button, "small");
|
||||
@@ -267,21 +274,11 @@ make_shader_stack (const char *name,
|
||||
return vbox;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_provider (gpointer data)
|
||||
{
|
||||
GtkStyleProvider *provider = GTK_STYLE_PROVIDER (data);
|
||||
|
||||
gtk_style_context_remove_provider_for_display (gdk_display_get_default (), provider);
|
||||
g_object_unref (provider);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_gltransition_window (GtkWidget *do_widget)
|
||||
{
|
||||
GtkWidget *window, *headerbar, *scale, *outer_grid, *grid, *background;
|
||||
GdkPaintable *paintable;
|
||||
GtkCssProvider *provider;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
|
||||
@@ -336,14 +333,6 @@ create_gltransition_window (GtkWidget *do_widget)
|
||||
make_shader_stack ("Kaleidoscope", "/gltransition/kaleidoscope.glsl", 3, scale),
|
||||
1, 1, 1, 1);
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_data (provider, "button.small { padding: 0; }", -1);
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (window), "provider", provider, remove_provider);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
|
@@ -9,8 +9,6 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <string.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
#define FOLDER_NAME "/iconview/gnome-fs-directory.png"
|
||||
|
@@ -8,8 +8,6 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <string.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
enum
|
||||
{
|
||||
COL_TEXT,
|
||||
|
@@ -7,8 +7,6 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
static GtkTreeModel *model = NULL;
|
||||
static guint timeout = 0;
|
||||
|
@@ -422,10 +422,6 @@ do_listview_settings (GtkWidget *do_widget)
|
||||
gtk_column_view_column_set_sorter (name_column, sorter);
|
||||
g_object_unref (sorter);
|
||||
|
||||
sorter = GTK_SORTER (gtk_string_sorter_new (gtk_property_expression_new (SETTINGS_TYPE_KEY, NULL, "type")));
|
||||
gtk_column_view_column_set_sorter (type_column, sorter);
|
||||
g_object_unref (sorter);
|
||||
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
|
@@ -10,6 +10,7 @@
|
||||
#include "script-names.h"
|
||||
#include "unicode-names.h"
|
||||
|
||||
|
||||
#define UCD_TYPE_ITEM (ucd_item_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (UcdItem, ucd_item, UCD, ITEM, GObject)
|
||||
|
||||
@@ -337,15 +338,6 @@ create_ucd_view (GtkWidget *label)
|
||||
|
||||
static GtkWidget *window;
|
||||
|
||||
static void
|
||||
remove_provider (gpointer data)
|
||||
{
|
||||
GtkStyleProvider *provider = GTK_STYLE_PROVIDER (data);
|
||||
|
||||
gtk_style_context_remove_provider_for_display (gdk_display_get_default (), provider);
|
||||
g_object_unref (provider);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_listview_ucd (GtkWidget *do_widget)
|
||||
{
|
||||
@@ -368,7 +360,7 @@ do_listview_ucd (GtkWidget *do_widget)
|
||||
gtk_widget_add_css_class (label, "enormous");
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_data (provider, "label.enormous { font-size: 80px; }", -1);
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (), GTK_STYLE_PROVIDER (provider), 800);
|
||||
gtk_style_context_add_provider (gtk_widget_get_style_context (label), GTK_STYLE_PROVIDER (provider), 800);
|
||||
gtk_widget_set_hexpand (label, TRUE);
|
||||
gtk_box_append (GTK_BOX (box), label);
|
||||
|
||||
@@ -378,8 +370,6 @@ do_listview_ucd (GtkWidget *do_widget)
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), listview);
|
||||
gtk_box_prepend (GTK_BOX (box), sw);
|
||||
gtk_window_set_child (GTK_WINDOW (window), box);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (window), "provider", provider, remove_provider);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
@@ -5,6 +5,7 @@ demos = files([
|
||||
'assistant.c',
|
||||
'builder.c',
|
||||
'clipboard.c',
|
||||
'colorspaces.c',
|
||||
'combobox.c',
|
||||
'constraints.c',
|
||||
'constraints_interactive.c',
|
||||
|
@@ -8,7 +8,6 @@
|
||||
#include "config.h"
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
/* Create an object for the pegs that get moved around in the game.
|
||||
*
|
||||
* We implement the GdkPaintable interface for them, so we can use GtkPicture
|
||||
@@ -360,15 +359,6 @@ drop_drop (GtkDropTarget *target,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_provider (gpointer data)
|
||||
{
|
||||
GtkStyleProvider *provider = GTK_STYLE_PROVIDER (data);
|
||||
|
||||
gtk_style_context_remove_provider_for_display (gdk_display_get_default (), provider);
|
||||
g_object_unref (provider);
|
||||
}
|
||||
|
||||
static void
|
||||
create_board (GtkWidget *window)
|
||||
{
|
||||
@@ -385,9 +375,6 @@ create_board (GtkWidget *window)
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_data (provider, css, -1);
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
800);
|
||||
|
||||
grid = gtk_grid_new ();
|
||||
gtk_widget_set_halign (grid, GTK_ALIGN_CENTER);
|
||||
@@ -406,6 +393,9 @@ create_board (GtkWidget *window)
|
||||
continue;
|
||||
|
||||
image = gtk_image_new ();
|
||||
gtk_style_context_add_provider (gtk_widget_get_style_context (image),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
800);
|
||||
gtk_widget_add_css_class (image, "solitaire-field");
|
||||
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
|
||||
if (x != 3 || y != 3)
|
||||
@@ -449,7 +439,7 @@ create_board (GtkWidget *window)
|
||||
}
|
||||
}
|
||||
|
||||
g_object_set_data_full (G_OBJECT (window), "provider", provider, remove_provider);
|
||||
g_object_unref (provider);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -123,14 +123,8 @@ do_pickers (GtkWidget *do_widget)
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_hexpand (label, TRUE);
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
picker = gtk_app_chooser_button_new ("x-scheme-handler/mailto");
|
||||
gtk_app_chooser_button_set_show_dialog_item (GTK_APP_CHOOSER_BUTTON (picker), TRUE);
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
gtk_grid_attach (GTK_GRID (table), label, 0, 3, 1, 1);
|
||||
gtk_grid_attach (GTK_GRID (table), picker, 1, 3, 1, 1);
|
||||
}
|
||||
|
@@ -16,6 +16,7 @@ enum {
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
static void
|
||||
pixbuf_paintable_snapshot (GdkPaintable *paintable,
|
||||
GdkSnapshot *snapshot,
|
||||
@@ -36,6 +37,7 @@ pixbuf_paintable_snapshot (GdkPaintable *paintable,
|
||||
|
||||
g_object_unref (texture);
|
||||
}
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
|
||||
static int
|
||||
pixbuf_paintable_get_intrinsic_width (GdkPaintable *paintable)
|
||||
|
BIN
demos/gtk-demo/sRGB_Gray-expected-result-no-cm.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
demos/gtk-demo/sRGB_Gray.jpg
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
demos/gtk-demo/sRGB_Gray.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
demos/gtk-demo/sRGB_Gray.tif
Normal file
@@ -16,6 +16,24 @@
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
/* Convenience function to create a combo box holding a number of strings
|
||||
*/
|
||||
GtkWidget *
|
||||
create_combo_box (const char **strings)
|
||||
{
|
||||
GtkWidget *combo_box;
|
||||
const char **str;
|
||||
|
||||
combo_box = gtk_combo_box_text_new ();
|
||||
|
||||
for (str = strings; *str; str++)
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_box), *str);
|
||||
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0);
|
||||
|
||||
return combo_box;
|
||||
}
|
||||
|
||||
static void
|
||||
add_row (GtkGrid *table,
|
||||
int row,
|
||||
@@ -23,7 +41,7 @@ add_row (GtkGrid *table,
|
||||
const char *label_text,
|
||||
const char **options)
|
||||
{
|
||||
GtkWidget *dropdown;
|
||||
GtkWidget *combo_box;
|
||||
GtkWidget *label;
|
||||
|
||||
label = gtk_label_new_with_mnemonic (label_text);
|
||||
@@ -32,12 +50,12 @@ add_row (GtkGrid *table,
|
||||
gtk_widget_set_hexpand (label, TRUE);
|
||||
gtk_grid_attach (table, label, 0, row, 1, 1);
|
||||
|
||||
dropdown = gtk_drop_down_new_from_strings (options);
|
||||
gtk_label_set_mnemonic_widget (GTK_LABEL (label), dropdown);
|
||||
gtk_widget_set_halign (dropdown, GTK_ALIGN_END);
|
||||
gtk_widget_set_valign (dropdown, GTK_ALIGN_BASELINE);
|
||||
gtk_size_group_add_widget (size_group, dropdown);
|
||||
gtk_grid_attach (table, dropdown, 1, row, 1, 1);
|
||||
combo_box = create_combo_box (options);
|
||||
gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo_box);
|
||||
gtk_widget_set_halign (combo_box, GTK_ALIGN_END);
|
||||
gtk_widget_set_valign (combo_box, GTK_ALIGN_BASELINE);
|
||||
gtk_size_group_add_widget (size_group, combo_box);
|
||||
gtk_grid_attach (table, combo_box, 1, row, 1, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -11,7 +11,6 @@
|
||||
#include <stdlib.h> /* for exit() */
|
||||
#include "paintable.h"
|
||||
|
||||
|
||||
static void easter_egg_callback (GtkWidget *button, gpointer data);
|
||||
|
||||
static void
|
||||
@@ -430,11 +429,11 @@ attach_widgets (GtkTextView *text_view)
|
||||
}
|
||||
else if (i == 1)
|
||||
{
|
||||
const char *options[] = {
|
||||
"Option 1", "Option 2", "Option 3", NULL
|
||||
};
|
||||
widget = gtk_combo_box_text_new ();
|
||||
|
||||
widget = gtk_drop_down_new_from_strings (options);
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), "Option 1");
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), "Option 2");
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), "Option 3");
|
||||
}
|
||||
else if (i == 2)
|
||||
{
|
||||
|
@@ -10,8 +10,6 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
/* TreeItem structure */
|
||||
typedef struct _TreeItem TreeItem;
|
||||
struct _TreeItem
|
||||
|
BIN
demos/widget-factory/color-profile-check.jpeg
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
demos/widget-factory/color-profile-check.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
demos/widget-factory/color-profile-check.tiff
Normal file
BIN
demos/widget-factory/hdr-example.heif
Executable file
256
demos/widget-factory/heif-loader.c
Normal file
@@ -0,0 +1,256 @@
|
||||
#include "heif-loader.h"
|
||||
#include <gtk/gtk.h>
|
||||
#include <libheif/heif.h>
|
||||
|
||||
static void
|
||||
describe_nclx_color_profile (const struct heif_color_profile_nclx *nclx,
|
||||
GString *s)
|
||||
{
|
||||
if (nclx->color_primaries == heif_color_primaries_unspecified)
|
||||
return;
|
||||
|
||||
if (nclx->color_primaries == heif_color_primaries_ITU_R_BT_709_5)
|
||||
{
|
||||
if (nclx->transfer_characteristics == heif_transfer_characteristic_IEC_61966_2_1 &&
|
||||
(nclx->matrix_coefficients == heif_matrix_coefficients_ITU_R_BT_470_6_System_B_G ||
|
||||
nclx->matrix_coefficients == heif_matrix_coefficients_ITU_R_BT_601_6))
|
||||
{
|
||||
g_string_append (s, "sRGB");
|
||||
return;
|
||||
}
|
||||
|
||||
if (nclx->transfer_characteristics == heif_transfer_characteristic_linear &&
|
||||
(nclx->matrix_coefficients == heif_matrix_coefficients_ITU_R_BT_470_6_System_B_G ||
|
||||
nclx->matrix_coefficients == heif_matrix_coefficients_ITU_R_BT_601_6))
|
||||
{
|
||||
g_string_append (s, "sRGB linear");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (nclx->color_primaries == heif_color_primaries_ITU_R_BT_2020_2_and_2100_0)
|
||||
{
|
||||
if (nclx->transfer_characteristics == heif_transfer_characteristic_ITU_R_BT_2100_0_PQ &&
|
||||
nclx->matrix_coefficients == heif_matrix_coefficients_ITU_R_BT_2020_2_non_constant_luminance)
|
||||
{
|
||||
g_string_append (s, "BT.2020 PQ");
|
||||
return;
|
||||
}
|
||||
|
||||
if (nclx->transfer_characteristics == heif_transfer_characteristic_ITU_R_BT_2100_0_HLG &&
|
||||
nclx->matrix_coefficients == heif_matrix_coefficients_ITU_R_BT_2020_2_non_constant_luminance)
|
||||
{
|
||||
g_string_append (s, "BT.2020 HLG");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (nclx->color_primaries == heif_color_primaries_SMPTE_EG_432_1)
|
||||
{
|
||||
if (nclx->transfer_characteristics == heif_transfer_characteristic_ITU_R_BT_2100_0_PQ)
|
||||
{
|
||||
g_string_append (s, "P3 PQ");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
g_string_append_printf (s, "%d/%d/%d",
|
||||
nclx->color_primaries,
|
||||
nclx->matrix_coefficients,
|
||||
nclx->transfer_characteristics);
|
||||
}
|
||||
|
||||
GdkTexture *
|
||||
load_heif_image (const char *resource_path,
|
||||
GString *details,
|
||||
GError **error)
|
||||
{
|
||||
struct heif_context *ctx;
|
||||
struct heif_error err;
|
||||
struct heif_image_handle *handle = NULL;
|
||||
struct heif_image *image = NULL;
|
||||
enum heif_chroma chroma;
|
||||
GdkMemoryFormat format;
|
||||
const char *format_name;
|
||||
uint8_t *data = NULL;
|
||||
gsize size;
|
||||
int width, height, bpp, stride, bits;
|
||||
GBytes *bytes;
|
||||
GdkTexture *texture = NULL;
|
||||
GdkColorSpace *color_space = NULL;
|
||||
char *profile_type = NULL;
|
||||
|
||||
ctx = heif_context_alloc ();
|
||||
|
||||
bytes = g_resources_lookup_data (resource_path, 0, NULL);
|
||||
data = (uint8_t *) g_bytes_get_data (bytes, &size);
|
||||
|
||||
err = heif_context_read_from_memory (ctx, data, size, NULL);
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
if (err.code != heif_error_Ok)
|
||||
{
|
||||
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, err.message);
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = heif_context_get_primary_image_handle (ctx, &handle);
|
||||
if (err.code != heif_error_Ok)
|
||||
{
|
||||
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, err.message);
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (heif_image_handle_get_color_profile_type (handle))
|
||||
{
|
||||
case heif_color_profile_type_not_present:
|
||||
break;
|
||||
case heif_color_profile_type_rICC:
|
||||
case heif_color_profile_type_prof:
|
||||
{
|
||||
guchar *icc_data;
|
||||
gsize icc_size;
|
||||
|
||||
profile_type = g_strdup ("icc");
|
||||
icc_size = heif_image_handle_get_raw_color_profile_size (handle);
|
||||
icc_data = g_new0 (guchar, icc_size);
|
||||
err = heif_image_handle_get_raw_color_profile (handle, icc_data);
|
||||
if (err.code == heif_error_Ok)
|
||||
{
|
||||
bytes = g_bytes_new (icc_data, icc_size);
|
||||
color_space = gdk_color_space_new_from_icc_profile (bytes, NULL);
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
g_free (icc_data);
|
||||
}
|
||||
break;
|
||||
case heif_color_profile_type_nclx:
|
||||
{
|
||||
struct heif_color_profile_nclx *nclx = NULL;
|
||||
|
||||
err = heif_image_handle_get_nclx_color_profile (handle, &nclx);
|
||||
if (err.code == heif_error_Ok)
|
||||
{
|
||||
GString *s;
|
||||
|
||||
s = g_string_new ("");
|
||||
describe_nclx_color_profile (nclx, s);
|
||||
profile_type = g_string_free (s, FALSE);
|
||||
color_space = gdk_color_space_new_from_cicp (nclx->color_primaries,
|
||||
nclx->transfer_characteristics,
|
||||
0,
|
||||
TRUE);
|
||||
heif_nclx_color_profile_free (nclx);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
g_string_append_printf (details, "%d × %d pixels\n%d bits of luma, %d bits of chroma%s\n",
|
||||
heif_image_handle_get_width (handle),
|
||||
heif_image_handle_get_height (handle),
|
||||
heif_image_handle_get_luma_bits_per_pixel (handle),
|
||||
heif_image_handle_get_chroma_bits_per_pixel (handle),
|
||||
heif_image_handle_has_alpha_channel (handle) ? ", with alpha" : "");
|
||||
|
||||
if (profile_type)
|
||||
{
|
||||
g_string_append_printf (details, "color profile: %s\n", profile_type);
|
||||
g_free (profile_type);
|
||||
}
|
||||
|
||||
if (color_space == NULL)
|
||||
color_space = g_object_ref (gdk_color_space_get_srgb ());
|
||||
|
||||
if (heif_image_handle_has_alpha_channel (handle))
|
||||
{
|
||||
if (heif_image_handle_get_luma_bits_per_pixel (handle) > 8 ||
|
||||
heif_image_handle_get_chroma_bits_per_pixel (handle) > 8)
|
||||
{
|
||||
chroma = heif_chroma_interleaved_RRGGBBAA_BE;
|
||||
format = GDK_MEMORY_R16G16B16A16;
|
||||
format_name = "R<sub>16</sub>G<sub>16</sub>B<sub>16</sub>A<sub>16</sub>";
|
||||
}
|
||||
else
|
||||
{
|
||||
chroma = heif_chroma_interleaved_RGBA;
|
||||
format = GDK_MEMORY_R8G8B8A8;
|
||||
format_name = "R<sub>8</sub>G<sub>8</sub>B<sub>8</sub>A<sub>8</sub>";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (heif_image_handle_get_luma_bits_per_pixel (handle) > 8 ||
|
||||
heif_image_handle_get_chroma_bits_per_pixel (handle) > 8)
|
||||
{
|
||||
chroma = heif_chroma_interleaved_RRGGBB_BE;
|
||||
format = GDK_MEMORY_R16G16B16;
|
||||
format_name = "R<sub>16</sub>G<sub>16</sub>B<sub>16</sub>";
|
||||
}
|
||||
else
|
||||
{
|
||||
chroma = heif_chroma_interleaved_RGB;
|
||||
format = GDK_MEMORY_R8G8B8;
|
||||
format_name = "R<sub>8</sub>G<sub>8</sub>B<sub>8</sub>";
|
||||
}
|
||||
}
|
||||
|
||||
err = heif_decode_image (handle, &image, heif_colorspace_RGB, chroma, NULL);
|
||||
if (err.code != heif_error_Ok)
|
||||
{
|
||||
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, err.message);
|
||||
goto out;
|
||||
}
|
||||
|
||||
width = heif_image_get_width (image, heif_channel_interleaved);
|
||||
height = heif_image_get_height (image, heif_channel_interleaved);
|
||||
bpp = heif_image_get_bits_per_pixel (image, heif_channel_interleaved);
|
||||
data = (uint8_t*)heif_image_get_plane_readonly (image, heif_channel_interleaved, &stride);
|
||||
bits = heif_image_get_bits_per_pixel_range (image, heif_channel_interleaved);
|
||||
|
||||
g_string_append_printf (details, "texture format %s", format_name);
|
||||
|
||||
if (format == GDK_MEMORY_R16G16B16A16 || format == GDK_MEMORY_R16G16B16)
|
||||
{
|
||||
/* Shift image data to full 16bit range */
|
||||
int shift = 16 - bits;
|
||||
if (shift > 0)
|
||||
{
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
uint8_t *row = data + y * stride;
|
||||
|
||||
for (int x = 0; x < stride; x += 2)
|
||||
{
|
||||
uint8_t* p = &row[x];
|
||||
int v = (p[0] << 8) | p[1];
|
||||
v = (v << shift) | (v >> (16 - shift));
|
||||
p[1] = (uint8_t) (v >> 8);
|
||||
p[0] = (uint8_t) (v & 0xFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bytes = g_bytes_new_with_free_func (data, height * stride * bpp, (GDestroyNotify)heif_image_release, image);
|
||||
|
||||
image = NULL;
|
||||
|
||||
texture = gdk_memory_texture_new_with_color_space (width, height,
|
||||
format, color_space,
|
||||
bytes, stride);
|
||||
g_bytes_unref (bytes);
|
||||
g_object_unref (color_space);
|
||||
|
||||
out:
|
||||
heif_context_free (ctx);
|
||||
if (handle)
|
||||
heif_image_handle_release (handle);
|
||||
if (image)
|
||||
heif_image_release (image);
|
||||
|
||||
return texture;
|
||||
}
|
7
demos/widget-factory/heif-loader.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
GdkTexture *load_heif_image (const char *resource_path,
|
||||
GString *details,
|
||||
GError **error);
|
BIN
demos/widget-factory/linear-gradient-color.png
Normal file
After Width: | Height: | Size: 213 B |
BIN
demos/widget-factory/linear-gradient-monochrome.png
Normal file
After Width: | Height: | Size: 220 B |
@@ -73,10 +73,18 @@ else
|
||||
)
|
||||
endif
|
||||
|
||||
widgetfactory_cflags = []
|
||||
widgetfactory_sources = [ 'widget-factory.c' ]
|
||||
|
||||
if libheif_dep.found()
|
||||
widgetfactory_cflags += '-DHAVE_LIBHEIF'
|
||||
widgetfactory_sources += 'heif-loader.c'
|
||||
endif
|
||||
|
||||
executable('gtk4-widget-factory',
|
||||
sources: ['widget-factory.c', widgetfactory_resources],
|
||||
c_args: common_cflags,
|
||||
dependencies: [ libgtk_dep, demo_conf_h ],
|
||||
sources: [ widgetfactory_sources, widgetfactory_resources],
|
||||
c_args: [ common_cflags, widgetfactory_cflags ],
|
||||
dependencies: [ libgtk_dep, libheif_dep, demo_conf_h ],
|
||||
include_directories: confinc,
|
||||
win_subsystem: 'windows',
|
||||
link_args: extra_demo_ldflags,
|
||||
|
BIN
demos/widget-factory/srgb-gradient-color.png
Normal file
After Width: | Height: | Size: 154 B |
BIN
demos/widget-factory/srgb-gradient-monochrome.png
Normal file
After Width: | Height: | Size: 164 B |
@@ -27,6 +27,8 @@
|
||||
|
||||
#include "demo_conf.h"
|
||||
|
||||
#include "heif-loader.h"
|
||||
|
||||
static void
|
||||
change_dark_state (GSimpleAction *action,
|
||||
GVariant *state,
|
||||
@@ -664,7 +666,6 @@ on_record_button_toggled (GtkToggleButton *button,
|
||||
gtk_widget_add_css_class (GTK_WIDGET (button), "destructive-action");
|
||||
}
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
static void
|
||||
on_page_combo_changed (GtkComboBox *combo,
|
||||
gpointer user_data)
|
||||
@@ -706,7 +707,6 @@ on_page_combo_changed (GtkComboBox *combo,
|
||||
default:;
|
||||
}
|
||||
}
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
static void
|
||||
on_range_from_changed (GtkSpinButton *from)
|
||||
@@ -845,7 +845,6 @@ page_changed_cb (GtkWidget *stack, GParamSpec *pspec, gpointer data)
|
||||
}
|
||||
}
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
static void
|
||||
populate_model (GtkTreeStore *store)
|
||||
{
|
||||
@@ -963,7 +962,6 @@ row_separator_func (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
|
||||
|
||||
return is_sep;
|
||||
}
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
static void
|
||||
update_title_header (GtkListBoxRow *row,
|
||||
@@ -1582,7 +1580,6 @@ osd_frame_pressed (GtkGestureClick *gesture,
|
||||
return GDK_EVENT_STOP;
|
||||
}
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
static gboolean
|
||||
page_combo_separator_func (GtkTreeModel *model,
|
||||
GtkTreeIter *iter,
|
||||
@@ -1597,7 +1594,6 @@ page_combo_separator_func (GtkTreeModel *model,
|
||||
|
||||
return res;
|
||||
}
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
static void
|
||||
toggle_format (GSimpleAction *action,
|
||||
@@ -1850,7 +1846,6 @@ update_buttons (GtkWidget *iv, GtkIconSize size)
|
||||
gtk_widget_set_sensitive (button, size != GTK_ICON_SIZE_INHERIT);
|
||||
}
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
static void
|
||||
increase_icon_size (GtkWidget *iv)
|
||||
{
|
||||
@@ -1901,7 +1896,6 @@ reset_icon_size (GtkWidget *iv)
|
||||
|
||||
gtk_widget_queue_resize (iv);
|
||||
}
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
static char *
|
||||
scale_format_value_blank (GtkScale *scale, double value, gpointer user_data)
|
||||
@@ -2278,12 +2272,10 @@ activate (GApplication *app)
|
||||
g_object_set_data (G_OBJECT (window), "selection_flowbox", widget2);
|
||||
g_signal_connect_swapped (widget, "clicked", G_CALLBACK (populate_flowbox), widget2);
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
widget = (GtkWidget *)gtk_builder_get_object (builder, "charletree");
|
||||
populate_model ((GtkTreeStore *)gtk_tree_view_get_model (GTK_TREE_VIEW (widget)));
|
||||
gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW (widget), row_separator_func, NULL, NULL);
|
||||
gtk_tree_view_expand_all (GTK_TREE_VIEW (widget));
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
widget = GTK_WIDGET (gtk_builder_get_object (builder, "munsell"));
|
||||
widget2 = GTK_WIDGET (gtk_builder_get_object (builder, "cchooser"));
|
||||
@@ -2291,7 +2283,6 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
populate_colors (widget, widget2);
|
||||
g_signal_connect (widget2, "notify::rgba", G_CALLBACK (rgba_changed), widget);
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
widget = (GtkWidget *)gtk_builder_get_object (builder, "page_combo");
|
||||
gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (widget), page_combo_separator_func, NULL, NULL);
|
||||
widget2 = (GtkWidget *)gtk_builder_get_object (builder, "range_from_spin");
|
||||
@@ -2302,7 +2293,6 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
g_object_set_data (G_OBJECT (widget), "range_to_spin", widget3);
|
||||
g_object_set_data (G_OBJECT (widget2), "range_to_spin", widget3);
|
||||
g_object_set_data (G_OBJECT (widget), "print_button", widget4);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
widget2 = (GtkWidget *)gtk_builder_get_object (builder, "tooltextview");
|
||||
|
||||
@@ -2395,6 +2385,20 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
model = (GMenuModel *)gtk_builder_get_object (builder, "new_style_context_menu_model");
|
||||
set_up_context_popover (widget, model);
|
||||
|
||||
widget = (GtkWidget *)gtk_builder_get_object (builder, "hdr_picture");
|
||||
#ifdef HAVE_LIBHEIF
|
||||
widget2 = (GtkWidget *)gtk_builder_get_object (builder, "hdr_label");
|
||||
GString *details = g_string_new ("");
|
||||
GdkTexture *texture = load_heif_image ("/org/gtk/WidgetFactory4/hdr-example.heif", details, NULL);
|
||||
gtk_picture_set_paintable (GTK_PICTURE (widget), GDK_PAINTABLE (texture));
|
||||
gtk_label_set_label (GTK_LABEL (widget2), details->str);
|
||||
g_string_free (details, TRUE);
|
||||
g_object_unref (texture);
|
||||
#else
|
||||
widget2 = gtk_widget_get_ancestor (widget, GTK_TYPE_NOTEBOOK);
|
||||
gtk_notebook_remove_page (GTK_NOTEBOOK (widget2), 2);
|
||||
#endif
|
||||
|
||||
gtk_window_present (window);
|
||||
|
||||
g_object_unref (builder);
|
||||
|
@@ -6,3 +6,10 @@
|
||||
.toolbar {
|
||||
-gtk-icon-style: symbolic;
|
||||
}
|
||||
|
||||
.gtk-gradient-color {
|
||||
background: linear-gradient(to right, lime, red);
|
||||
}
|
||||
.gtk-gradient-monochrome {
|
||||
background: linear-gradient(to right, black, white);
|
||||
}
|
||||
|
@@ -110,6 +110,7 @@
|
||||
<file>icons/scalable/status/weather-severe-alert-symbolic.svg</file>
|
||||
<file>icons/scalable/status/weather-showers-symbolic.svg</file>
|
||||
<file>icons/scalable/status/weather-snow-symbolic.svg</file>
|
||||
<file>hdr-example.heif</file>
|
||||
|
||||
<file alias='icons/scalable/apps/org.gtk.WidgetFactory4.svg'>data/scalable/apps/org.gtk.WidgetFactory4.svg</file>
|
||||
|
||||
@@ -120,5 +121,12 @@
|
||||
<file>portland-rose.jpg</file>
|
||||
<file>nyc.jpg</file>
|
||||
<file>beach.jpg</file>
|
||||
<file>linear-gradient-color.png</file>
|
||||
<file>linear-gradient-monochrome.png</file>
|
||||
<file>srgb-gradient-color.png</file>
|
||||
<file>srgb-gradient-monochrome.png</file>
|
||||
<file>color-profile-check.png</file>
|
||||
<file>color-profile-check.jpeg</file>
|
||||
<file>color-profile-check.tiff</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
@@ -1347,13 +1347,173 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child>
|
||||
<object class="GtkNotebookPage">
|
||||
<property name="child">
|
||||
<object class="GtkBox" id="box8">
|
||||
<property name="orientation">1</property>
|
||||
<object class="GtkGrid">
|
||||
<property name="hexpand">0</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<property name="column-spacing">6</property>
|
||||
<property name="margin-start">6</property>
|
||||
<property name="margin-end">6</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<property name="row-homogeneous">1</property>
|
||||
<property name="valign">start</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">color</property>
|
||||
<style>
|
||||
<class name="caption-heading"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">0</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">sRGB</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkPicture">
|
||||
<property name="file">resource:///org/gtk/WidgetFactory4/srgb-gradient-color.png</property>
|
||||
<property name="can-shrink">0</property>
|
||||
<property name="keep-aspect-ratio">0</property>
|
||||
<property name="hexpand">1</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">GTK</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkPicture">
|
||||
<property name="width-request">128</property>
|
||||
<property name="keep-aspect-ratio">0</property>
|
||||
<style>
|
||||
<class name="gtk-gradient-color"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">linear</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkPicture">
|
||||
<property name="file">resource:///org/gtk/WidgetFactory4/linear-gradient-color.png</property>
|
||||
<property name="can-shrink">0</property>
|
||||
<property name="keep-aspect-ratio">0</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">monochrome</property>
|
||||
<style>
|
||||
<class name="caption-heading"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">4</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">sRGB</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">5</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkPicture">
|
||||
<property name="file">resource:///org/gtk/WidgetFactory4/srgb-gradient-monochrome.png</property>
|
||||
<property name="can-shrink">0</property>
|
||||
<property name="keep-aspect-ratio">0</property>
|
||||
<property name="hexpand">1</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">5</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">GTK</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">6</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkPicture">
|
||||
<property name="width-request">128</property>
|
||||
<property name="keep-aspect-ratio">0</property>
|
||||
<style>
|
||||
<class name="gtk-gradient-monochrome"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">6</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">linear</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">7</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkPicture">
|
||||
<property name="file">resource:///org/gtk/WidgetFactory4/linear-gradient-monochrome.png</property>
|
||||
<property name="can-shrink">0</property>
|
||||
<property name="keep-aspect-ratio">0</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">7</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label8">
|
||||
<property name="label" translatable="1">page 1</property>
|
||||
<property name="label" translatable="1">Gradients</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1362,13 +1522,92 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<object class="GtkNotebookPage">
|
||||
<property name="position">1</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox" id="box10">
|
||||
<property name="orientation">1</property>
|
||||
<object class="GtkGrid">
|
||||
<property name="hexpand">0</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<property name="column-spacing">6</property>
|
||||
<property name="margin-start">6</property>
|
||||
<property name="margin-end">6</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<property name="row-homogeneous">1</property>
|
||||
<property name="valign">start</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">image loading</property>
|
||||
<style>
|
||||
<class name="caption-heading"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">0</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///org/gtk/WidgetFactory4/color-profile-check.png</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">PNG</property>
|
||||
<property name="hexpand">1</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///org/gtk/WidgetFactory4/color-profile-check.jpeg</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">JPEG</property>
|
||||
<property name="hexpand">1</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///org/gtk/WidgetFactory4/color-profile-check.tiff</property>
|
||||
<layout>
|
||||
|
||||
<property name="column">0</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">TIFF</property>
|
||||
<property name="hexpand">1</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label9">
|
||||
<property name="label" translatable="1">page 2</property>
|
||||
<property name="label" translatable="1">Images</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1378,12 +1617,26 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="position">2</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox" id="box11">
|
||||
<property name="orientation">1</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkPicture" id="hdr_picture">
|
||||
<property name="can-shrink">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="hdr_label">
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
<property name="margin-top">10</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<property name="use-markup">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label10">
|
||||
<property name="label" translatable="1">page 3</property>
|
||||
<property name="label" translatable="1">HDR</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -3345,12 +3598,10 @@ bad things might happen.</property>
|
||||
<attribute name="display-hint">circular-buttons</attribute>
|
||||
<item>
|
||||
<attribute name="verb-icon">printer-symbolic</attribute>
|
||||
<attribute name="label" translatable="yes">Print all the things!</attribute>
|
||||
<attribute name="action">win.print</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="verb-icon">emblem-shared-symbolic</attribute>
|
||||
<attribute name="label" translatable="yes">Share all the things!</attribute>
|
||||
<attribute name="action">app.share</attribute>
|
||||
</item>
|
||||
</section>
|
||||
@@ -3365,17 +3616,14 @@ bad things might happen.</property>
|
||||
<attribute name="label" translatable="yes">Edit</attribute>
|
||||
<item>
|
||||
<attribute name="verb-icon">edit-cut-symbolic</attribute>
|
||||
<attribute name="label" translatable="yes">Cut</attribute>
|
||||
<attribute name="action">app.cut</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="verb-icon">edit-copy-symbolic</attribute>
|
||||
<attribute name="label" translatable="yes">Copy</attribute>
|
||||
<attribute name="action">app.copy</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="verb-icon">edit-paste-symbolic</attribute>
|
||||
<attribute name="label" translatable="yes">Paste</attribute>
|
||||
<attribute name="action">app.paste</attribute>
|
||||
</item>
|
||||
</section>
|
||||
|
@@ -12,8 +12,8 @@ SYNOPSIS
|
||||
--------
|
||||
| **gtk4-builder-tool** <COMMAND> [OPTIONS...] <FILE>
|
||||
|
|
||||
| **gtk4-builder-tool** validate [OPTIONS...] <FILE>
|
||||
| **gtk4-builder-tool** enumerate [OPTIONS...] <FILE>
|
||||
| **gtk4-builder-tool** validate <FILE>
|
||||
| **gtk4-builder-tool** enumerate <FILE>
|
||||
| **gtk4-builder-tool** simplify [OPTIONS...] <FILE>
|
||||
| **gtk4-builder-tool** preview [OPTIONS...] <FILE>
|
||||
| **gtk4-builder-tool** screenshot [OPTIONS...] <FILE>
|
||||
@@ -33,20 +33,12 @@ Validation
|
||||
The ``validate`` command validates the given UI definition file and reports
|
||||
errors to ``stderr``.
|
||||
|
||||
``--deprecations``
|
||||
|
||||
Warn about uses of deprecated types in the UI definition file.
|
||||
|
||||
Enumeration
|
||||
^^^^^^^^^^^
|
||||
|
||||
The ``enumerate`` command prints all the named objects that are present in the UI
|
||||
The ``enumerate`` command lists all the named objects that are present in the UI
|
||||
definition file.
|
||||
|
||||
``--callbacks``
|
||||
|
||||
Print the names of callbacks as well.
|
||||
|
||||
Preview
|
||||
^^^^^^^
|
||||
|
||||
|
@@ -1,74 +0,0 @@
|
||||
Title: Preparing for GTK 5
|
||||
Slug: gtk-migrating-4-to-5
|
||||
|
||||
GTK 5 will be a major new version of GTK that breaks both API and
|
||||
ABI compared to GTK 4.x. GTK 5 does not exist yet, so we cannot
|
||||
be entirely sure what will be involved in a migration from GTK 4
|
||||
to GTK 5. But we can already give some preliminary hints about
|
||||
the likely changes, and how to prepare for them in code that is
|
||||
using GTK 4.
|
||||
|
||||
### Do not use deprecated symbols
|
||||
|
||||
As always, functions and types that are known to go away in the
|
||||
next major version of GTK are being marked as deprecated in GTK 4.
|
||||
|
||||
Removing the use of deprecated APIs is the most important step
|
||||
to prepare your code for the next major version of GTK. Often,
|
||||
deprecation notes will include hints about replacement APIs to
|
||||
help you with this.
|
||||
|
||||
Sometimes, it is helpful to have some background information about
|
||||
the motivation and goals of larger API changes.
|
||||
|
||||
## Cell renderers are going away
|
||||
|
||||
Cell renderers were introduced in GTK 2 to support rendering of
|
||||
"big data" UIs, in particular treeviews. Over the years, more
|
||||
"data-like" widgets have started to use them, and cell renderers
|
||||
have grown into a shadowy, alternative rendering infrastructure
|
||||
that duplicates much of what widgets do, while duplicating the
|
||||
code and adding their own dose of bugs.
|
||||
|
||||
In GTK 4, replacement widgets for GtkTreeView, GtkIconView and
|
||||
GtkComboBox have appeared: GtkListView, GtkColumnView, GtkGridView
|
||||
and GtkDropDown. For GTK 5, we will take the next step and remove
|
||||
all cell renderer-based widgets.
|
||||
|
||||
## Themed rendering APIs are going away
|
||||
|
||||
The old GTK 2 era rendering APIs for theme components like
|
||||
gtk_render_frame() or gtk_render_check() have not been used by
|
||||
GTK itself even in later GTK 3, but they have been kepy around
|
||||
for the benefit of "external drawing" users - applications that
|
||||
want their controls to look like GTK without using widgets.
|
||||
|
||||
Supporting this is increasingly getting in the way of making
|
||||
the GTK CSS machinery fast and correct. One notable problem is
|
||||
that temporary style changes (using gtk_style_context_save())
|
||||
is breaking animations. Therefore, these APIs will be going away
|
||||
in GTK 5, together with their more modern GtkSnapshot variants
|
||||
like gtk_snapshot_render_background() or gtk_snapshot_render_focus().
|
||||
|
||||
The best way to render parts of your widget using CSS styling
|
||||
is to use subwidgets. For example, to show a piece of text with
|
||||
fonts, effects and shadows according to the current CSS style,
|
||||
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].
|
||||
|
||||
## Local stylesheets are going away
|
||||
|
||||
The cascading part of GTK's CSS implementation is complicated by
|
||||
the existence of local stylesheets (i.e. those added with
|
||||
gtk_style_context_add_provider()). And local stylesheets are
|
||||
unintuitive in that they do not apply to the whole subtree of
|
||||
widgets, but just to the one widget where the stylesheet was
|
||||
added.
|
||||
|
||||
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.
|
@@ -92,7 +92,8 @@ Specifies a list of directories to search when GTK is looking for
|
||||
dynamically loaded objects such as input method modules and print
|
||||
backends. If the path to the dynamically loaded object is given as
|
||||
an absolute path name, then GTK loads it directly. Otherwise, GTK
|
||||
goes in turn through the directories in `GTK_PATH`, followed
|
||||
goes in turn through the directories in `GTK_PATH`, followed by
|
||||
the directory `.gtk-4.0` in the user's home directory, followed
|
||||
by the system default directory, which is `libdir/gtk-4.0/modules`.
|
||||
(If `GTK_EXE_PREFIX` is defined, `libdir` is `$GTK_EXE_PREFIX/lib`.
|
||||
Otherwise it is the libdir specified when GTK was configured, usually
|
||||
|
@@ -1,13 +1,6 @@
|
||||
Title: Tree and List Widget Overview
|
||||
Slug: gtk-treeview
|
||||
|
||||
This document describes the `GtkTreeView` widget and auxiliary
|
||||
classes, like tree models and cell renderers. All of these have
|
||||
been deprecated and will be removed in GTK 5. Their replacements
|
||||
are described in the [List Widget Overview](section-list-widget.html).
|
||||
|
||||
## Introduction
|
||||
|
||||
To create a tree or list in GTK, use the `GtkTreeModel` interface in
|
||||
conjunction with the `GtkTreeView` widget. This widget is designed around
|
||||
a _Model/View/Controller_ design and consists of four major parts:
|
||||
|
@@ -350,8 +350,7 @@ quit_activated (GSimpleAction *action,
|
||||
}
|
||||
|
||||
static void
|
||||
combo_changed (GtkDropDown *combo,
|
||||
GParamSpec *pspec,
|
||||
combo_changed (GtkComboBox *combo,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkDialog *dialog = user_data;
|
||||
@@ -360,7 +359,7 @@ combo_changed (GtkDropDown *combo,
|
||||
char **accels;
|
||||
char *str;
|
||||
|
||||
action = gtk_string_object_get_string (GTK_STRING_OBJECT (gtk_drop_down_get_selected_item (combo)));
|
||||
action = gtk_combo_box_get_active_id (combo);
|
||||
|
||||
if (!action)
|
||||
return;
|
||||
@@ -389,7 +388,7 @@ response (GtkDialog *dialog,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkEntry *entry = g_object_get_data (user_data, "entry");
|
||||
GtkDropDown *combo = g_object_get_data (user_data, "combo");
|
||||
GtkComboBox *combo = g_object_get_data (user_data, "combo");
|
||||
const char *action;
|
||||
const char *str;
|
||||
char **accels;
|
||||
@@ -400,7 +399,7 @@ response (GtkDialog *dialog,
|
||||
return;
|
||||
}
|
||||
|
||||
action = gtk_string_object_get_string (GTK_STRING_OBJECT (gtk_drop_down_get_selected_item (combo)));
|
||||
action = gtk_combo_box_get_active_id (combo);
|
||||
|
||||
if (!action)
|
||||
return;
|
||||
@@ -425,7 +424,6 @@ edit_accels (GSimpleAction *action,
|
||||
char **actions;
|
||||
GtkWidget *dialog;
|
||||
int i;
|
||||
GtkStringList *strings;
|
||||
|
||||
dialog = gtk_dialog_new_with_buttons ("Accelerators",
|
||||
NULL,
|
||||
@@ -437,8 +435,7 @@ edit_accels (GSimpleAction *action,
|
||||
gtk_window_set_application (GTK_WINDOW (dialog), app);
|
||||
actions = gtk_application_list_action_descriptions (app);
|
||||
|
||||
strings = gtk_string_list_new (NULL);
|
||||
combo = gtk_drop_down_new (G_LIST_MODEL (strings), NULL);
|
||||
combo = gtk_combo_box_text_new ();
|
||||
g_object_set (gtk_dialog_get_content_area (GTK_DIALOG (dialog)),
|
||||
"margin-top", 10,
|
||||
"margin-bottom", 10,
|
||||
@@ -449,8 +446,8 @@ edit_accels (GSimpleAction *action,
|
||||
|
||||
gtk_box_append (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), combo);
|
||||
for (i = 0; actions[i]; i++)
|
||||
gtk_string_list_append (strings, actions[i]);
|
||||
g_signal_connect (combo, "notify::selected", G_CALLBACK (combo_changed), dialog);
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), actions[i], actions[i]);
|
||||
g_signal_connect (combo, "changed", G_CALLBACK (combo_changed), dialog);
|
||||
|
||||
entry = gtk_entry_new ();
|
||||
gtk_widget_set_hexpand (entry, TRUE);
|
||||
@@ -461,7 +458,7 @@ edit_accels (GSimpleAction *action,
|
||||
g_object_set_data (G_OBJECT (dialog), "combo", combo);
|
||||
g_object_set_data (G_OBJECT (dialog), "entry", entry);
|
||||
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (combo), 0);
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
|
||||
|
||||
gtk_widget_show (dialog);
|
||||
}
|
||||
|
@@ -39,26 +39,19 @@ gdk_broadway_cairo_context_begin_frame (GdkDrawContext *draw_context,
|
||||
{
|
||||
GdkBroadwayCairoContext *self = GDK_BROADWAY_CAIRO_CONTEXT (draw_context);
|
||||
GdkSurface *surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self));
|
||||
cairo_t *cr;
|
||||
cairo_region_t *repaint_region;
|
||||
int width, height, scale;
|
||||
int width, height;
|
||||
|
||||
width = gdk_surface_get_width (surface);
|
||||
height = gdk_surface_get_height (surface);
|
||||
scale = gdk_surface_get_scale_factor (surface);
|
||||
self->paint_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
width * scale, height * scale);
|
||||
cairo_surface_set_device_scale (self->paint_surface, scale, scale);
|
||||
self->paint_surface = gdk_surface_create_similar_surface (surface,
|
||||
CAIRO_CONTENT_COLOR_ALPHA,
|
||||
width,
|
||||
height);
|
||||
|
||||
repaint_region = cairo_region_create_rectangle (&(cairo_rectangle_int_t) { 0, 0, width, height });
|
||||
cairo_region_union (region, repaint_region);
|
||||
cairo_region_destroy (repaint_region);
|
||||
|
||||
/* clear the repaint area */
|
||||
cr = cairo_create (self->paint_surface);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
|
||||
cairo_fill (cr);
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -262,8 +262,7 @@ _gdk_broadway_events_got_input (GdkDisplay *display,
|
||||
message->key.state,
|
||||
FALSE,
|
||||
&translated,
|
||||
&translated,
|
||||
NULL);
|
||||
&translated);
|
||||
|
||||
node = _gdk_event_queue_append (display, event);
|
||||
_gdk_windowing_got_event (display, node, event, message->base.serial);
|
||||
|
@@ -19,7 +19,7 @@
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -130,6 +130,7 @@ static const GdkDebugKey gdk_debug_keys[] = {
|
||||
{ "vulkan-validate", GDK_DEBUG_VULKAN_VALIDATE, "Load the Vulkan validation layer", TRUE },
|
||||
{ "default-settings",GDK_DEBUG_DEFAULT_SETTINGS, "Force default values for xsettings", TRUE },
|
||||
{ "high-depth", GDK_DEBUG_HIGH_DEPTH, "Use high bit depth rendering if possible", TRUE },
|
||||
{ "srgb", GDK_DEBUG_SRGB, "Force sRRGB rendering and turn off color profiles", TRUE },
|
||||
};
|
||||
|
||||
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include <gdk/gdkcairo.h>
|
||||
#include <gdk/gdkcairocontext.h>
|
||||
#include <gdk/gdkclipboard.h>
|
||||
#include <gdk/gdkcolorspace.h>
|
||||
#include <gdk/gdkconfig.h>
|
||||
#include <gdk/gdkcontentdeserializer.h>
|
||||
#include <gdk/gdkcontentformats.h>
|
||||
|
114
gdk/gdkcairo.c
@@ -1,5 +1,5 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2005 Red Hat, Inc.
|
||||
* Copyright (C) 2005 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
|
||||
@@ -19,6 +19,10 @@
|
||||
|
||||
#include "gdkcairoprivate.h"
|
||||
|
||||
#include "gdkcolorspace.h"
|
||||
#include "gdkcolorprivate.h"
|
||||
#include "gdkmemoryformatprivate.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
@@ -32,14 +36,20 @@ void
|
||||
gdk_cairo_set_source_rgba (cairo_t *cr,
|
||||
const GdkRGBA *rgba)
|
||||
{
|
||||
GdkColor color;
|
||||
const float *components;
|
||||
|
||||
g_return_if_fail (cr != NULL);
|
||||
g_return_if_fail (rgba != NULL);
|
||||
|
||||
gdk_color_convert_rgba (&color, gdk_cairo_get_color_space (cr), rgba);
|
||||
components = gdk_color_get_components (&color);
|
||||
cairo_set_source_rgba (cr,
|
||||
rgba->red,
|
||||
rgba->green,
|
||||
rgba->blue,
|
||||
rgba->alpha);
|
||||
components[0],
|
||||
components[1],
|
||||
components[2],
|
||||
gdk_color_get_alpha (&color));
|
||||
gdk_color_finish (&color);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -335,3 +345,97 @@ gdk_cairo_region_from_clip (cairo_t *cr)
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
static cairo_user_data_key_t color_space_key;
|
||||
|
||||
/**
|
||||
* gdk_cairo_surface_set_color_space:
|
||||
* @surface: a surface
|
||||
* @color_space: the color space to attach to the surface
|
||||
*
|
||||
* Attaches a `GdkColorSpace` to the Cairo surface.
|
||||
*
|
||||
* This is just auxiliary data for use by GTK, no Cairo functions
|
||||
* do interact with this information.
|
||||
*
|
||||
* Note that all Cairo compositing operations are assumed to happen
|
||||
* in a linear RGB color space, so if you want to use the surface
|
||||
* as a target for rendering in a color managed way, you should use
|
||||
* such a color space.
|
||||
*
|
||||
* The default color space is assumed to be sRGB, which is not
|
||||
* linear.
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
void
|
||||
gdk_cairo_surface_set_color_space (cairo_surface_t *surface,
|
||||
GdkColorSpace *color_space)
|
||||
{
|
||||
g_return_if_fail (surface != NULL);
|
||||
g_return_if_fail (GDK_IS_COLOR_SPACE (color_space));
|
||||
|
||||
cairo_surface_set_user_data (surface,
|
||||
&color_space_key,
|
||||
g_object_ref (color_space),
|
||||
g_object_unref);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_cairo_surface_get_color_space:
|
||||
* @surface: a surface
|
||||
*
|
||||
* Gets the color space GTK assumes for the surface. See
|
||||
* [method@Gdk.CairoSurface.set_color_space] for details.
|
||||
*
|
||||
* Returns: (transfer none): the color space
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
GdkColorSpace *
|
||||
gdk_cairo_surface_get_color_space (cairo_surface_t *surface)
|
||||
{
|
||||
GdkColorSpace *color_space;
|
||||
|
||||
g_return_val_if_fail (surface != NULL, gdk_color_space_get_srgb ());
|
||||
|
||||
color_space = cairo_surface_get_user_data (surface, &color_space_key);
|
||||
if (color_space == NULL)
|
||||
color_space = gdk_color_space_get_srgb ();
|
||||
|
||||
return color_space;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_cairo_get_color_space:
|
||||
* @cr: a cairo context
|
||||
*
|
||||
* Gets the color space GTK assumes for the cairo context.
|
||||
*
|
||||
* Returns: (transfer none): the color space
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
GdkColorSpace *
|
||||
gdk_cairo_get_color_space (cairo_t *cr)
|
||||
{
|
||||
GdkColorSpace *color_space;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
g_return_val_if_fail (cr != NULL, gdk_color_space_get_srgb ());
|
||||
|
||||
surface = cairo_get_group_target (cr);
|
||||
color_space = cairo_surface_get_user_data (surface, &color_space_key);
|
||||
if (color_space != NULL)
|
||||
return color_space;
|
||||
|
||||
/* theoretically, we should walk the whole group stack, but I don't
|
||||
* think Cairo lets us do that
|
||||
*/
|
||||
surface = cairo_get_target (cr);
|
||||
color_space = cairo_surface_get_user_data (surface, &color_space_key);
|
||||
if (color_space != NULL)
|
||||
return color_space;
|
||||
|
||||
return gdk_color_space_get_srgb ();
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2005 Red Hat, Inc.
|
||||
* Copyright (C) 2005 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
|
||||
@@ -46,9 +46,15 @@ void gdk_cairo_region (cairo_t *cr,
|
||||
const cairo_region_t *region);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
cairo_region_t *
|
||||
gdk_cairo_region_create_from_surface
|
||||
(cairo_surface_t *surface);
|
||||
cairo_region_t * gdk_cairo_region_create_from_surface (cairo_surface_t *surface);
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
void gdk_cairo_surface_set_color_space (cairo_surface_t *surface,
|
||||
GdkColorSpace *color_space);
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GdkColorSpace * gdk_cairo_surface_get_color_space (cairo_surface_t *surface);
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GdkColorSpace * gdk_cairo_get_color_space (cairo_t *cr);
|
||||
|
||||
GDK_DEPRECATED_IN_4_6_FOR(gdk_gl_texture_new)
|
||||
void gdk_cairo_draw_from_gl (cairo_t *cr,
|
||||
|
273
gdk/gdkcicpcolorspace.c
Normal file
@@ -0,0 +1,273 @@
|
||||
/* gdkcicpcolorspace.c
|
||||
*
|
||||
* Copyright 2022 (c) 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 "gdkcicpcolorspaceprivate.h"
|
||||
#include "gdklcmscolorspaceprivate.h"
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
struct _GdkCicpColorSpace
|
||||
{
|
||||
GdkColorSpace parent_instance;
|
||||
|
||||
int color_primaries;
|
||||
int transfer_characteristics;
|
||||
int matrix_coefficients;
|
||||
gboolean full_range;
|
||||
|
||||
GdkColorSpace *lcms;
|
||||
};
|
||||
|
||||
struct _GdkCicpColorSpaceClass
|
||||
{
|
||||
GdkColorSpaceClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GdkCicpColorSpace, gdk_cicp_color_space, GDK_TYPE_COLOR_SPACE)
|
||||
|
||||
static gboolean
|
||||
gdk_cicp_color_space_supports_format (GdkColorSpace *space,
|
||||
GdkMemoryFormat format)
|
||||
{
|
||||
GdkCicpColorSpace *self = GDK_CICP_COLOR_SPACE (space);
|
||||
|
||||
if (self->lcms)
|
||||
return gdk_color_space_supports_format (self->lcms, format);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
gdk_cicp_color_space_save_to_icc_profile (GdkColorSpace *space,
|
||||
GError **error)
|
||||
{
|
||||
GdkCicpColorSpace *self = GDK_CICP_COLOR_SPACE (space);
|
||||
|
||||
if (self->lcms)
|
||||
return gdk_color_space_save_to_icc_profile (self->lcms, error);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
gdk_cicp_color_space_get_n_components (GdkColorSpace *space)
|
||||
{
|
||||
GdkCicpColorSpace *self = GDK_CICP_COLOR_SPACE (space);
|
||||
|
||||
if (self->lcms)
|
||||
return gdk_color_space_get_n_components (self->lcms);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_cicp_color_space_dispose (GObject *object)
|
||||
{
|
||||
GdkCicpColorSpace *self = GDK_CICP_COLOR_SPACE (object);
|
||||
|
||||
g_clear_object (&self->lcms);
|
||||
|
||||
G_OBJECT_CLASS (gdk_cicp_color_space_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_cicp_color_space_class_init (GdkCicpColorSpaceClass *klass)
|
||||
{
|
||||
GdkColorSpaceClass *color_space_class = GDK_COLOR_SPACE_CLASS (klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
color_space_class->supports_format = gdk_cicp_color_space_supports_format;
|
||||
color_space_class->save_to_icc_profile = gdk_cicp_color_space_save_to_icc_profile;
|
||||
color_space_class->get_n_components = gdk_cicp_color_space_get_n_components;
|
||||
|
||||
gobject_class->dispose = gdk_cicp_color_space_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_cicp_color_space_init (GdkCicpColorSpace *self)
|
||||
{
|
||||
}
|
||||
|
||||
static GdkColorSpace *
|
||||
lcms_from_cicp (int color_primaries,
|
||||
int transfer_characteristics,
|
||||
int matrix_coefficients,
|
||||
gboolean full_range)
|
||||
{
|
||||
cmsHPROFILE profile = NULL;
|
||||
cmsCIExyY whitepoint;
|
||||
cmsCIExyYTRIPLE primaries;
|
||||
cmsToneCurve *curve[3];
|
||||
cmsCIExyY whiteD65 = (cmsCIExyY) { 0.3127, 0.3290, 1.0 };
|
||||
cmsCIExyY whiteC = (cmsCIExyY) { 0.310, 0.316, 1.0 };
|
||||
cmsFloat64Number srgb_parameters[5] =
|
||||
{ 2.4, 1.0 / 1.055, 0.055 / 1.055, 1.0 / 12.92, 0.04045 };
|
||||
cmsFloat64Number rec709_parameters[5] =
|
||||
{ 2.2, 1.0 / 1.099, 0.099 / 1.099, 1.0 / 4.5, 0.081 };
|
||||
|
||||
/* We only support full-range RGB profiles */
|
||||
g_assert (matrix_coefficients == 0);
|
||||
g_assert (full_range);
|
||||
|
||||
if (color_primaries == 0 /* ITU_R_BT_709_5 */)
|
||||
{
|
||||
if (transfer_characteristics == 13 /* IEC_61966_2_1 */)
|
||||
return g_object_ref (gdk_color_space_get_srgb ());
|
||||
else if (transfer_characteristics == 8 /* linear */)
|
||||
return g_object_ref (gdk_color_space_get_srgb_linear ());
|
||||
}
|
||||
switch (color_primaries)
|
||||
{
|
||||
case 1:
|
||||
primaries.Green = (cmsCIExyY) { 0.300, 0.600, 1.0 };
|
||||
primaries.Blue = (cmsCIExyY) { 0.150, 0.060, 1.0 };
|
||||
primaries.Red = (cmsCIExyY) { 0.640, 0.330, 1.0 };
|
||||
whitepoint = whiteD65;
|
||||
break;
|
||||
case 4:
|
||||
primaries.Green = (cmsCIExyY) { 0.21, 0.71, 1.0 };
|
||||
primaries.Blue = (cmsCIExyY) { 0.14, 0.08, 1.0 };
|
||||
primaries.Red = (cmsCIExyY) { 0.67, 0.33, 1.0 };
|
||||
whitepoint = whiteC;
|
||||
break;
|
||||
case 5:
|
||||
primaries.Green = (cmsCIExyY) { 0.29, 0.60, 1.0 };
|
||||
primaries.Blue = (cmsCIExyY) { 0.15, 0.06, 1.0 };
|
||||
primaries.Red = (cmsCIExyY) { 0.64, 0.33, 1.0 };
|
||||
whitepoint = whiteD65;
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
primaries.Green = (cmsCIExyY) { 0.310, 0.595, 1.0 };
|
||||
primaries.Blue = (cmsCIExyY) { 0.155, 0.070, 1.0 };
|
||||
primaries.Red = (cmsCIExyY) { 0.630, 0.340, 1.0 };
|
||||
whitepoint = whiteD65;
|
||||
break;
|
||||
case 8:
|
||||
primaries.Green = (cmsCIExyY) { 0.243, 0.692, 1.0 };
|
||||
primaries.Blue = (cmsCIExyY) { 0.145, 0.049, 1.0 };
|
||||
primaries.Red = (cmsCIExyY) { 0.681, 0.319, 1.0 };
|
||||
whitepoint = whiteC;
|
||||
break;
|
||||
case 9:
|
||||
primaries.Green = (cmsCIExyY) { 0.170, 0.797, 1.0 };
|
||||
primaries.Blue = (cmsCIExyY) { 0.131, 0.046, 1.0 };
|
||||
primaries.Red = (cmsCIExyY) { 0.708, 0.292, 1.0 };
|
||||
whitepoint = whiteD65;
|
||||
break;
|
||||
case 10:
|
||||
primaries.Green = (cmsCIExyY) { 0.0, 1.0, 1.0 };
|
||||
primaries.Blue = (cmsCIExyY) { 0.0, 0.0, 1.0 };
|
||||
primaries.Red = (cmsCIExyY) { 1.0, 0.0, 1.0 };
|
||||
whitepoint = (cmsCIExyY) { 0.333333, 0.333333, 1.0 };
|
||||
break;
|
||||
case 11:
|
||||
primaries.Green = (cmsCIExyY) { 0.265, 0.690, 1.0 };
|
||||
primaries.Blue = (cmsCIExyY) { 0.150, 0.060, 1.0 };
|
||||
primaries.Red = (cmsCIExyY) { 0.680, 0.320, 1.0 };
|
||||
whitepoint = (cmsCIExyY) { 0.314, 0.351, 1.0 };
|
||||
break;
|
||||
case 12:
|
||||
primaries.Green = (cmsCIExyY) { 0.265, 0.690, 1.0 };
|
||||
primaries.Blue = (cmsCIExyY) { 0.150, 0.060, 1.0 };
|
||||
primaries.Red = (cmsCIExyY) { 0.680, 0.320, 1.0 };
|
||||
whitepoint = whiteD65;
|
||||
break;
|
||||
case 22:
|
||||
primaries.Green = (cmsCIExyY) { 0.295, 0.605, 1.0 };
|
||||
primaries.Blue = (cmsCIExyY) { 0.155, 0.077, 1.0 };
|
||||
primaries.Red = (cmsCIExyY) { 0.630, 0.340, 1.0 };
|
||||
whitepoint = whiteD65;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (transfer_characteristics)
|
||||
{
|
||||
case 1: /* ITU_R_BT_709_5 */
|
||||
curve[0] = curve[1] = curve[2] = cmsBuildParametricToneCurve (NULL, 4,
|
||||
rec709_parameters);
|
||||
profile = cmsCreateRGBProfile (&whitepoint, &primaries, curve);
|
||||
cmsFreeToneCurve (curve[0]);
|
||||
break;
|
||||
case 4: /* ITU_R_BT_470_6_System_M */
|
||||
curve[0] = curve[1] = curve[2] = cmsBuildGamma (NULL, 2.2f);
|
||||
profile = cmsCreateRGBProfile (&whitepoint, &primaries, curve);
|
||||
cmsFreeToneCurve (curve[0]);
|
||||
break;
|
||||
case 5: /* ITU_R_BT_470_6_System_B_G */
|
||||
curve[0] = curve[1] = curve[2] = cmsBuildGamma (NULL, 2.8f);
|
||||
profile = cmsCreateRGBProfile (&whitepoint, &primaries, curve);
|
||||
cmsFreeToneCurve (curve[0]);
|
||||
break;
|
||||
case 8: /* linear */
|
||||
curve[0] = curve[1] = curve[2] = cmsBuildGamma (NULL, 1.0f);
|
||||
profile = cmsCreateRGBProfile (&whitepoint, &primaries, curve);
|
||||
cmsFreeToneCurve (curve[0]);
|
||||
break;
|
||||
/* FIXME
|
||||
* We need to handle at least 16 (PQ) here.
|
||||
* Problem is: lcms can't do it
|
||||
*/
|
||||
case 13: /* IEC_61966_2_1 */
|
||||
default:
|
||||
curve[0] = curve[1] = curve[2] = cmsBuildParametricToneCurve (NULL, 4,
|
||||
srgb_parameters);
|
||||
profile = cmsCreateRGBProfile (&whitepoint, &primaries, curve);
|
||||
cmsFreeToneCurve (curve[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (profile)
|
||||
return gdk_lcms_color_space_new_from_lcms_profile (profile);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GdkColorSpace *
|
||||
gdk_color_space_new_from_cicp (int color_primaries,
|
||||
int transfer_characteristics,
|
||||
int matrix_coefficients,
|
||||
gboolean full_range)
|
||||
{
|
||||
GdkCicpColorSpace *result;
|
||||
|
||||
result = g_object_new (GDK_TYPE_CICP_COLOR_SPACE, NULL);
|
||||
result->color_primaries = color_primaries;
|
||||
result->transfer_characteristics = transfer_characteristics;
|
||||
result->matrix_coefficients = matrix_coefficients;
|
||||
result->full_range = full_range;
|
||||
|
||||
result->lcms = lcms_from_cicp (color_primaries,
|
||||
transfer_characteristics,
|
||||
matrix_coefficients,
|
||||
full_range);
|
||||
|
||||
return GDK_COLOR_SPACE (result);
|
||||
}
|
||||
|
||||
GdkColorSpace *
|
||||
gdk_cicp_color_space_get_lcms_color_space (GdkColorSpace *space)
|
||||
{
|
||||
GdkCicpColorSpace *self = GDK_CICP_COLOR_SPACE (space);
|
||||
|
||||
return self->lcms;
|
||||
}
|
45
gdk/gdkcicpcolorspaceprivate.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/* gdkcicpcolorspaceprivate.h
|
||||
*
|
||||
* Copyright 2022 (c) 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_CICP_COLOR_SPACE_PRIVATE_H__
|
||||
#define __GDK_CICP_COLOR_SPACE_PRIVATE_H__
|
||||
|
||||
#include "gdkcolorspaceprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_CICP_COLOR_SPACE (gdk_cicp_color_space_get_type ())
|
||||
|
||||
#define GDK_CICP_COLOR_SPACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_CICP_COLOR_SPACE, GdkCicpColorSpace))
|
||||
#define GDK_IS_CICP_COLOR_SPACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_CICP_COLOR_SPACE))
|
||||
#define GDK_CICP_COLOR_SPACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_CICP_COLOR_SPACE, GdkCicpColorSpaceClass))
|
||||
#define GDK_IS_CICP_COLOR_SPACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_CICP_COLOR_SPACE))
|
||||
#define GDK_CICP_COLOR_SPACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_CICP_COLOR_SPACE, GdkCicpColorSpaceClass))
|
||||
|
||||
typedef struct _GdkCicpColorSpace GdkCicpColorSpace;
|
||||
typedef struct _GdkCicpColorSpaceClass GdkCicpColorSpaceClass;
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkCicpColorSpace, g_object_unref)
|
||||
|
||||
GType gdk_cicp_color_space_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GdkColorSpace * gdk_cicp_color_space_get_lcms_color_space (GdkColorSpace *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_CICP_COLOR_SPACE_PRIVATE_H__ */
|
115
gdk/gdkcolor.c
Normal file
@@ -0,0 +1,115 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
*
|
||||
* Copyright (C) 2021 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 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 "gdkcolorprivate.h"
|
||||
#include "gdkcolorspaceprivate.h"
|
||||
#include "gdklcmscolorspaceprivate.h"
|
||||
|
||||
#include <lcms2.h>
|
||||
|
||||
static inline cmsHTRANSFORM *
|
||||
gdk_color_get_transform (GdkColorSpace *src,
|
||||
GdkColorSpace *dest)
|
||||
{
|
||||
return gdk_color_space_lookup_transform (src, TYPE_RGBA_FLT, dest, TYPE_RGBA_FLT);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_color_convert (GdkColor *self,
|
||||
GdkColorSpace *color_space,
|
||||
const GdkColor *other)
|
||||
{
|
||||
gdk_color_init (self,
|
||||
color_space,
|
||||
other->alpha,
|
||||
NULL,
|
||||
gdk_color_space_get_n_components (color_space));
|
||||
|
||||
cmsDoTransform (gdk_color_get_transform (other->color_space, color_space),
|
||||
gdk_color_get_components (other),
|
||||
(float *) gdk_color_get_components (self),
|
||||
1);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_color_convert_rgba (GdkColor *self,
|
||||
GdkColorSpace *color_space,
|
||||
const GdkRGBA *rgba)
|
||||
{
|
||||
gdk_color_init (self,
|
||||
color_space,
|
||||
rgba->alpha,
|
||||
NULL,
|
||||
gdk_color_space_get_n_components (color_space));
|
||||
|
||||
cmsDoTransform (gdk_color_get_transform (gdk_color_space_get_srgb (), color_space),
|
||||
(float[3]) { rgba->red, rgba->green, rgba->blue },
|
||||
(float *) gdk_color_get_components (self),
|
||||
1);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_color_mix (GdkColor *self,
|
||||
GdkColorSpace *color_space,
|
||||
const GdkColor *src1,
|
||||
const GdkColor *src2,
|
||||
double progress)
|
||||
{
|
||||
if (src1->color_space != color_space)
|
||||
{
|
||||
GdkColor tmp;
|
||||
gdk_color_convert (&tmp, color_space, src1);
|
||||
gdk_color_mix (self, color_space, &tmp, src2, progress);
|
||||
}
|
||||
else if (src2->color_space != color_space)
|
||||
{
|
||||
GdkColor tmp;
|
||||
gdk_color_convert (&tmp, color_space, src2);
|
||||
gdk_color_mix (self, color_space, src1, &tmp, progress);
|
||||
}
|
||||
else
|
||||
{
|
||||
gsize i, n;
|
||||
const float *s1, *s2;
|
||||
float *d;
|
||||
|
||||
n = gdk_color_space_get_n_components (color_space);
|
||||
|
||||
gdk_color_init (self,
|
||||
color_space,
|
||||
src1->alpha * (1.0 - progress) + src2->alpha * progress,
|
||||
NULL, n);
|
||||
|
||||
d = (float *) gdk_color_get_components (self);
|
||||
s1 = gdk_color_get_components (src1);
|
||||
s2 = gdk_color_get_components (src2);
|
||||
|
||||
if (self->alpha == 0)
|
||||
{
|
||||
for (i = 0; i < n; i++)
|
||||
d[i] = s1[i] * (1.0 - progress) + s2[i] * progress;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < n; i++)
|
||||
d[i] = (s1[i] * src1->alpha * (1.0 - progress) + s2[i] * src2->alpha * progress) / self->alpha;
|
||||
}
|
||||
}
|
||||
}
|
73
gdk/gdkcolorprivate.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
*
|
||||
* Copyright (C) 2021 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_COLOR_PRIVATE_H__
|
||||
#define __GDK_COLOR_PRIVATE_H__
|
||||
|
||||
#include <gdk/gdkcolorspace.h>
|
||||
#include <gdk/gdkrgba.h>
|
||||
|
||||
/* RGB - and it makes the struct size a multiple of 8 bytes, ie pointer-aligned */
|
||||
#define GDK_COLOR_MAX_NATIVE_COMPONENTS 3
|
||||
|
||||
typedef struct _GdkColor GdkColor;
|
||||
|
||||
struct _GdkColor
|
||||
{
|
||||
GdkColorSpace *color_space;
|
||||
float alpha;
|
||||
union {
|
||||
float values[GDK_COLOR_MAX_NATIVE_COMPONENTS];
|
||||
float *components;
|
||||
};
|
||||
};
|
||||
|
||||
G_STATIC_ASSERT (sizeof (GdkColor) % sizeof (gpointer) == 0);
|
||||
|
||||
static inline void gdk_color_init (GdkColor *self,
|
||||
GdkColorSpace *color_space,
|
||||
float alpha,
|
||||
float *components,
|
||||
gsize n_components);
|
||||
static inline void gdk_color_init_from_rgba (GdkColor *self,
|
||||
const GdkRGBA *rgba);
|
||||
static inline void gdk_color_finish (GdkColor *self);
|
||||
|
||||
void gdk_color_convert (GdkColor *self,
|
||||
GdkColorSpace *color_space,
|
||||
const GdkColor *other);
|
||||
void gdk_color_convert_rgba (GdkColor *self,
|
||||
GdkColorSpace *color_space,
|
||||
const GdkRGBA *rgba);
|
||||
|
||||
void gdk_color_mix (GdkColor *self,
|
||||
GdkColorSpace *color_space,
|
||||
const GdkColor *src1,
|
||||
const GdkColor *src2,
|
||||
double progress);
|
||||
|
||||
static inline GdkColorSpace * gdk_color_get_color_space (const GdkColor *self);
|
||||
static inline float gdk_color_get_alpha (const GdkColor *self);
|
||||
static inline const float * gdk_color_get_components (const GdkColor *self);
|
||||
static inline gsize gdk_color_get_n_components (const GdkColor *self);
|
||||
|
||||
#include "gdkcolorprivateimpl.h"
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
97
gdk/gdkcolorprivateimpl.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
*
|
||||
* Copyright (C) 2021 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 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/>.
|
||||
*/
|
||||
|
||||
static inline gboolean
|
||||
gdk_color_is_allocated (const GdkColor *self)
|
||||
{
|
||||
return GPOINTER_TO_SIZE (self->color_space) & 1;
|
||||
}
|
||||
|
||||
static inline void
|
||||
gdk_color_init (GdkColor *self,
|
||||
GdkColorSpace *color_space,
|
||||
float alpha,
|
||||
float *components,
|
||||
gsize n_components)
|
||||
{
|
||||
gboolean allocated = n_components > GDK_COLOR_MAX_NATIVE_COMPONENTS;
|
||||
|
||||
g_assert (n_components == gdk_color_space_get_n_components (color_space));
|
||||
|
||||
self->color_space = GSIZE_TO_POINTER (GPOINTER_TO_SIZE (g_object_ref (color_space)) | allocated);
|
||||
self->alpha = alpha;
|
||||
if (allocated)
|
||||
{
|
||||
if (components)
|
||||
self->components = g_memdup (components, sizeof (float) * n_components);
|
||||
else
|
||||
self->components = g_new (float, n_components);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (components)
|
||||
memcpy (self->values, components, sizeof (float) * n_components);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
gdk_color_init_from_rgba (GdkColor *self,
|
||||
const GdkRGBA *rgba)
|
||||
{
|
||||
gdk_color_init (self,
|
||||
gdk_color_space_get_srgb (),
|
||||
rgba->alpha,
|
||||
(float[3]) { rgba->red, rgba->green, rgba->blue },
|
||||
3);
|
||||
}
|
||||
|
||||
static inline void
|
||||
gdk_color_finish (GdkColor *self)
|
||||
{
|
||||
if (gdk_color_is_allocated (self))
|
||||
g_free (self->components);
|
||||
|
||||
g_object_unref (gdk_color_get_color_space (self));
|
||||
}
|
||||
|
||||
static inline GdkColorSpace *
|
||||
gdk_color_get_color_space (const GdkColor *self)
|
||||
{
|
||||
return GSIZE_TO_POINTER (GPOINTER_TO_SIZE (self->color_space) & ~1);
|
||||
}
|
||||
|
||||
static inline float
|
||||
gdk_color_get_alpha (const GdkColor *self)
|
||||
{
|
||||
return self->alpha;
|
||||
}
|
||||
|
||||
static inline const float *
|
||||
gdk_color_get_components (const GdkColor *self)
|
||||
{
|
||||
if (gdk_color_is_allocated (self))
|
||||
return self->components;
|
||||
else
|
||||
return self->values;
|
||||
}
|
||||
|
||||
static inline gsize
|
||||
gdk_color_get_n_components (const GdkColor *self)
|
||||
{
|
||||
return gdk_color_space_get_n_components (gdk_color_get_color_space (self));
|
||||
}
|
227
gdk/gdkcolorspace.c
Normal file
@@ -0,0 +1,227 @@
|
||||
/* gdkcolor_space.c
|
||||
*
|
||||
* Copyright 2021 (c) Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 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/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* GdkColorSpace:
|
||||
*
|
||||
* `GdkColorSpace` is used to describe color spaces.
|
||||
*
|
||||
* Tell developers what a color space is instead of just linking to
|
||||
* https://en.wikipedia.org/wiki/Color_space
|
||||
*
|
||||
* `GdkColorSpace` objects are immutable and therefore threadsafe.
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkcolorspaceprivate.h"
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
//static GParamSpec *properties[N_PROPS];
|
||||
|
||||
G_DEFINE_TYPE (GdkColorSpace, gdk_color_space, G_TYPE_OBJECT)
|
||||
|
||||
static gboolean
|
||||
gdk_color_space_default_supports_format (GdkColorSpace *self,
|
||||
GdkMemoryFormat format)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
gdk_color_space_default_save_to_icc_profile (GdkColorSpace *self,
|
||||
GError **error)
|
||||
{
|
||||
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("This color space does not support ICC profiles"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
gdk_color_space_default_get_n_components (GdkColorSpace *self)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_color_space_default_equal (GdkColorSpace *profile1,
|
||||
GdkColorSpace *profile2)
|
||||
{
|
||||
return profile1 == profile2;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_color_space_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
//GdkColorSpace *self = GDK_COLOR_SPACE (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_color_space_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
//GdkColorSpace *self = GDK_COLOR_SPACE (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_color_space_dispose (GObject *object)
|
||||
{
|
||||
//GdkColorSpace *self = GDK_COLOR_SPACE (object);
|
||||
|
||||
G_OBJECT_CLASS (gdk_color_space_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_color_space_class_init (GdkColorSpaceClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
klass->supports_format = gdk_color_space_default_supports_format;
|
||||
klass->save_to_icc_profile = gdk_color_space_default_save_to_icc_profile;
|
||||
klass->get_n_components = gdk_color_space_default_get_n_components;
|
||||
klass->equal = gdk_color_space_default_equal;
|
||||
|
||||
gobject_class->set_property = gdk_color_space_set_property;
|
||||
gobject_class->get_property = gdk_color_space_get_property;
|
||||
gobject_class->dispose = gdk_color_space_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_color_space_init (GdkColorSpace *self)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_color_space_supports_format:
|
||||
* @self: a `GdkColorSpace`
|
||||
* @format: the format to check
|
||||
*
|
||||
* Checks if this color space can be used with textures in the given format.
|
||||
*
|
||||
* Returns: %TRUE if this colorspace supports the format
|
||||
*
|
||||
* Since: 4.10
|
||||
**/
|
||||
gboolean
|
||||
gdk_color_space_supports_format (GdkColorSpace *self,
|
||||
GdkMemoryFormat format)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_COLOR_SPACE (self), FALSE);
|
||||
g_return_val_if_fail (format < GDK_MEMORY_N_FORMATS, FALSE);
|
||||
|
||||
return GDK_COLOR_SPACE_GET_CLASS (self)->supports_format (self, format);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_color_space_save_to_icc_profile:
|
||||
* @self: a `GdkColorSpace`
|
||||
* @error: Return location for an error
|
||||
*
|
||||
* Saves the color space to an
|
||||
* [ICC profile](https://en.wikipedia.org/wiki/ICC_profile).
|
||||
*
|
||||
* Some color spaces cannot be represented as ICC profiles. In
|
||||
* that case, an error will be set and %NULL will be returned.
|
||||
*
|
||||
* Returns: (nullable): A new `GBytes` containing the ICC profile
|
||||
*
|
||||
* Since: 4.10
|
||||
**/
|
||||
GBytes *
|
||||
gdk_color_space_save_to_icc_profile (GdkColorSpace *self,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_COLOR_SPACE (self), NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
return GDK_COLOR_SPACE_GET_CLASS (self)->save_to_icc_profile (self, error);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_color_space_is_linear (GdkColorSpace *self)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_COLOR_SPACE (self), FALSE);
|
||||
|
||||
return self == gdk_color_space_get_srgb_linear ();
|
||||
}
|
||||
|
||||
int
|
||||
gdk_color_space_get_n_components (GdkColorSpace *self)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_COLOR_SPACE (self), 0);
|
||||
|
||||
return GDK_COLOR_SPACE_GET_CLASS (self)->get_n_components (self);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_color_space_equal:
|
||||
* @profile1: (type GdkColorSpace): a `GdkColorSpace`
|
||||
* @profile2: (type GdkColorSpace): another `GdkColorSpace`
|
||||
*
|
||||
* Compares two `GdkColorSpace`s for equality.
|
||||
*
|
||||
* Note that this function is not guaranteed to be perfect and two objects
|
||||
* describing the same color space may compare not equal. However, different
|
||||
* color spaces will never compare equal.
|
||||
*
|
||||
* Returns: %TRUE if the two color profiles compare equal
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
gboolean
|
||||
gdk_color_space_equal (gconstpointer profile1,
|
||||
gconstpointer profile2)
|
||||
{
|
||||
if (profile1 == profile2)
|
||||
return TRUE;
|
||||
|
||||
if (GDK_COLOR_SPACE_GET_CLASS (profile1) == GDK_COLOR_SPACE_GET_CLASS (profile2))
|
||||
return GDK_COLOR_SPACE_GET_CLASS (profile1)->equal (GDK_COLOR_SPACE (profile1),
|
||||
GDK_COLOR_SPACE (profile2));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
81
gdk/gdkcolorspace.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/* gdkcolor_space.h
|
||||
*
|
||||
* Copyright 2021 (c) Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_COLOR_SPACE_H__
|
||||
#define __GDK_COLOR_SPACE_H__
|
||||
|
||||
#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkenums.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_COLOR_SPACE (gdk_color_space_get_type ())
|
||||
|
||||
#define GDK_COLOR_SPACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_COLOR_SPACE, GdkColorSpace))
|
||||
#define GDK_IS_COLOR_SPACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_COLOR_SPACE))
|
||||
#define GDK_COLOR_SPACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_COLOR_SPACE, GdkColorSpaceClass))
|
||||
#define GDK_IS_COLOR_SPACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_COLOR_SPACE))
|
||||
#define GDK_COLOR_SPACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_COLOR_SPACE, GdkColorSpaceClass))
|
||||
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkColorSpace, g_object_unref)
|
||||
|
||||
typedef struct _GdkColorSpaceClass GdkColorSpaceClass;
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GType gdk_color_space_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GdkColorSpace * gdk_color_space_get_srgb (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GdkColorSpace * gdk_color_space_new_from_icc_profile (GBytes *icc_profile,
|
||||
GError **error);
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GdkColorSpace * gdk_color_space_new_from_cicp (int color_primaries,
|
||||
int transfer_characteristics,
|
||||
int matrix_coefficients,
|
||||
gboolean full_range);
|
||||
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
gboolean gdk_color_space_supports_format (GdkColorSpace *self,
|
||||
GdkMemoryFormat format);
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GBytes * gdk_color_space_save_to_icc_profile (GdkColorSpace *self,
|
||||
GError **error);
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
gboolean gdk_color_space_is_linear (GdkColorSpace *self);
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
int gdk_color_space_get_n_components (GdkColorSpace *self);
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
gboolean gdk_color_space_equal (gconstpointer profile1,
|
||||
gconstpointer profile2);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_COLOR_SPACE_H__ */
|
39
gdk/gdkcolorspaceprivate.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef __GDK_COLOR_SPACE_PRIVATE_H__
|
||||
#define __GDK_COLOR_SPACE_PRIVATE_H__
|
||||
|
||||
#include "gdkcolorspace.h"
|
||||
#include <lcms2.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
struct _GdkColorSpace
|
||||
{
|
||||
GObject parent_instance;
|
||||
};
|
||||
|
||||
struct _GdkColorSpaceClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
gboolean (* supports_format) (GdkColorSpace *self,
|
||||
GdkMemoryFormat format);
|
||||
GBytes * (* save_to_icc_profile) (GdkColorSpace *self,
|
||||
GError **error);
|
||||
|
||||
int (* get_n_components) (GdkColorSpace *self);
|
||||
|
||||
gboolean (* equal) (GdkColorSpace *profile1,
|
||||
GdkColorSpace *profile2);
|
||||
};
|
||||
|
||||
|
||||
GdkColorSpace * gdk_color_space_get_srgb_linear (void) G_GNUC_CONST;
|
||||
|
||||
cmsHTRANSFORM * gdk_color_space_lookup_transform (GdkColorSpace *source,
|
||||
guint source_type,
|
||||
GdkColorSpace *dest,
|
||||
guint dest_type);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_COLOR_SPACE_PRIVATE_H__ */
|
@@ -16,8 +16,6 @@ G_BEGIN_DECLS
|
||||
#mesondefine GDK_WINDOWING_WAYLAND
|
||||
#mesondefine GDK_WINDOWING_WIN32
|
||||
|
||||
#mesondefine GDK_RENDERING_CAIRO
|
||||
#mesondefine GDK_RENDERING_GL
|
||||
#mesondefine GDK_RENDERING_VULKAN
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -879,7 +879,7 @@ file_text_serializer (GdkContentSerializer *serializer)
|
||||
g_string_append (str, path);
|
||||
g_free (path);
|
||||
if (l->next)
|
||||
g_string_append (str, "\n");
|
||||
g_string_append (str, " ");
|
||||
}
|
||||
path = g_string_free (str, FALSE);
|
||||
}
|
||||
|
@@ -51,6 +51,7 @@ typedef enum {
|
||||
GDK_DEBUG_VULKAN_VALIDATE = 1 << 23,
|
||||
GDK_DEBUG_DEFAULT_SETTINGS= 1 << 24,
|
||||
GDK_DEBUG_HIGH_DEPTH = 1 << 25,
|
||||
GDK_DEBUG_SRGB = 1 << 26,
|
||||
} GdkDebugFlags;
|
||||
|
||||
extern guint _gdk_debug_flags;
|
||||
|
@@ -1517,16 +1517,6 @@ gdk_button_event_get_button (GdkEvent *event)
|
||||
* An event related to a key-based device.
|
||||
*/
|
||||
|
||||
static void
|
||||
gdk_key_event_finalize (GdkEvent *event)
|
||||
{
|
||||
GdkKeyEvent *self = (GdkKeyEvent *) event;
|
||||
|
||||
g_free (self->compose_sequence);
|
||||
|
||||
GDK_EVENT_SUPER (event)->finalize (event);
|
||||
}
|
||||
|
||||
static GdkModifierType
|
||||
gdk_key_event_get_state (GdkEvent *event)
|
||||
{
|
||||
@@ -1538,7 +1528,7 @@ gdk_key_event_get_state (GdkEvent *event)
|
||||
static const GdkEventTypeInfo gdk_key_event_info = {
|
||||
sizeof (GdkKeyEvent),
|
||||
NULL,
|
||||
gdk_key_event_finalize,
|
||||
NULL,
|
||||
gdk_key_event_get_state,
|
||||
NULL,
|
||||
NULL,
|
||||
@@ -1562,10 +1552,6 @@ GDK_DEFINE_EVENT_TYPE (GdkKeyEvent, gdk_key_event,
|
||||
* @is_modifier: whether the event is a modifiers only event
|
||||
* @translated: the translated key data for the given @state
|
||||
* @no_lock: the translated key data without the given @state
|
||||
* @compose_sequence: (transfer none) (nullable):
|
||||
* The compose sequence string, either partial or only the
|
||||
* final composed string, if that can be determined at event
|
||||
* creation time. Used by selected IM modules.
|
||||
*
|
||||
* Creates a new `GdkKeyEvent`.
|
||||
*
|
||||
@@ -1580,8 +1566,7 @@ gdk_key_event_new (GdkEventType type,
|
||||
GdkModifierType state,
|
||||
gboolean is_modifier,
|
||||
GdkTranslatedKey *translated,
|
||||
GdkTranslatedKey *no_lock,
|
||||
char *compose_sequence)
|
||||
GdkTranslatedKey *no_lock)
|
||||
{
|
||||
g_return_val_if_fail (type == GDK_KEY_PRESS ||
|
||||
type == GDK_KEY_RELEASE, NULL);
|
||||
@@ -1594,7 +1579,6 @@ gdk_key_event_new (GdkEventType type,
|
||||
self->key_is_modifier = is_modifier;
|
||||
self->translated[0] = *translated;
|
||||
self->translated[1] = *no_lock;
|
||||
self->compose_sequence = g_strdup (compose_sequence);
|
||||
|
||||
return event;
|
||||
}
|
||||
@@ -1625,26 +1609,6 @@ gdk_key_event_get_translated_key (GdkEvent *event,
|
||||
return &(self->translated[0]);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_key_event_get_compose_sequence:
|
||||
* @event: (type GdkKeyEvent): a key event
|
||||
*
|
||||
* Extracts the compose sequence string from a key event.
|
||||
*
|
||||
* Returns: (transfer none): the compose sequence string
|
||||
*/
|
||||
char *
|
||||
gdk_key_event_get_compose_sequence (GdkEvent *event)
|
||||
{
|
||||
GdkKeyEvent *self = (GdkKeyEvent *) event;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_EVENT (event), 0);
|
||||
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_KEY_PRESS) ||
|
||||
GDK_IS_EVENT_TYPE (event, GDK_KEY_RELEASE), FALSE);
|
||||
|
||||
return self->compose_sequence;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_key_event_get_keyval:
|
||||
* @event: (type GdkKeyEvent): a key event
|
||||
|
@@ -259,9 +259,6 @@ typedef struct {
|
||||
* @keycode: the raw code of the key that was pressed or released.
|
||||
* @translated: the result of translating @keycode. First with the full
|
||||
* @state, then while ignoring Caps Lock.
|
||||
* @compose_sequence: optional string for use by selected IM modules.
|
||||
* Contains either partial compose sequences or the final composed
|
||||
* string of the keystroke sequence.
|
||||
*
|
||||
* Describes a key press or key release event.
|
||||
*/
|
||||
@@ -273,7 +270,6 @@ struct _GdkKeyEvent
|
||||
guint32 keycode;
|
||||
gboolean key_is_modifier;
|
||||
GdkTranslatedKey translated[2];
|
||||
char *compose_sequence;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -474,8 +470,7 @@ GdkEvent * gdk_key_event_new (GdkEventType type,
|
||||
GdkModifierType modifiers,
|
||||
gboolean is_modifier,
|
||||
GdkTranslatedKey *translated,
|
||||
GdkTranslatedKey *no_lock,
|
||||
char *compose_sequence);
|
||||
GdkTranslatedKey *no_lock);
|
||||
|
||||
GdkEvent * gdk_focus_event_new (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
@@ -602,8 +597,6 @@ GdkEvent * gdk_grab_broken_event_new (GdkSurface *surface,
|
||||
GdkTranslatedKey * gdk_key_event_get_translated_key (GdkEvent *event,
|
||||
gboolean no_lock);
|
||||
|
||||
char * gdk_key_event_get_compose_sequence (GdkEvent *event);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
/* Following flag is set for events on the event queue during
|
||||
@@ -633,6 +626,7 @@ void _gdk_event_queue_flush (GdkDisplay *display);
|
||||
|
||||
double * gdk_event_dup_axes (GdkEvent *event);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_EVENTS_PRIVATE_H__ */
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkglcontextprivate.h"
|
||||
#include "gdkmemoryformatprivate.h"
|
||||
#include "gdkcolorspace.h"
|
||||
#include "gdkmemorytextureprivate.h"
|
||||
#include "gdktextureprivate.h"
|
||||
|
||||
@@ -38,6 +39,7 @@ struct _GdkGLTexture {
|
||||
GdkTexture parent_instance;
|
||||
|
||||
GdkGLContext *context;
|
||||
GdkGLTextureFlags flags;
|
||||
guint id;
|
||||
|
||||
GdkTexture *saved;
|
||||
@@ -115,6 +117,7 @@ typedef struct _Download Download;
|
||||
struct _Download
|
||||
{
|
||||
GdkMemoryFormat format;
|
||||
GdkColorSpace *color_space;
|
||||
guchar *data;
|
||||
gsize stride;
|
||||
};
|
||||
@@ -157,7 +160,7 @@ gdk_gl_texture_do_download (gpointer texture_,
|
||||
expected_stride = texture->width * gdk_memory_format_bytes_per_pixel (download->format);
|
||||
|
||||
if (download->stride == expected_stride &&
|
||||
!gdk_gl_context_get_use_es (self->context) &&
|
||||
!gdk_gl_context_get_use_es (self->context) &&
|
||||
gdk_memory_format_gl_format (download->format, TRUE, &gl_internal_format, &gl_format, &gl_type))
|
||||
{
|
||||
glGetTexImage (GL_TEXTURE_2D,
|
||||
@@ -193,7 +196,7 @@ gdk_gl_texture_do_download (gpointer texture_,
|
||||
(download->stride == expected_stride))
|
||||
{
|
||||
glReadPixels (0, 0,
|
||||
texture->width, texture->height,
|
||||
texture->width, texture->height,
|
||||
gl_read_format,
|
||||
gl_read_type,
|
||||
download->data);
|
||||
@@ -204,7 +207,7 @@ gdk_gl_texture_do_download (gpointer texture_,
|
||||
guchar *pixels = g_malloc_n (texture->width * actual_bpp, texture->height);
|
||||
|
||||
glReadPixels (0, 0,
|
||||
texture->width, texture->height,
|
||||
texture->width, texture->height,
|
||||
gl_read_format,
|
||||
gl_read_type,
|
||||
pixels);
|
||||
@@ -212,9 +215,11 @@ gdk_gl_texture_do_download (gpointer texture_,
|
||||
gdk_memory_convert (download->data,
|
||||
download->stride,
|
||||
download->format,
|
||||
download->color_space,
|
||||
pixels,
|
||||
texture->width * actual_bpp,
|
||||
actual_format,
|
||||
gdk_color_space_get_srgb (),
|
||||
texture->width,
|
||||
texture->height);
|
||||
|
||||
@@ -228,6 +233,7 @@ gdk_gl_texture_do_download (gpointer texture_,
|
||||
static void
|
||||
gdk_gl_texture_download (GdkTexture *texture,
|
||||
GdkMemoryFormat format,
|
||||
GdkColorSpace *color_space,
|
||||
guchar *data,
|
||||
gsize stride)
|
||||
{
|
||||
@@ -236,11 +242,12 @@ gdk_gl_texture_download (GdkTexture *texture,
|
||||
|
||||
if (self->saved)
|
||||
{
|
||||
gdk_texture_do_download (self->saved, format, data, stride);
|
||||
gdk_texture_do_download (self->saved, format, color_space, data, stride);
|
||||
return;
|
||||
}
|
||||
|
||||
download.format = format;
|
||||
download.color_space = color_space;
|
||||
download.data = data;
|
||||
download.stride = stride;
|
||||
|
||||
@@ -275,6 +282,12 @@ gdk_gl_texture_get_id (GdkGLTexture *self)
|
||||
return self->id;
|
||||
}
|
||||
|
||||
GdkGLTextureFlags
|
||||
gdk_gl_texture_get_flags (GdkGLTexture *self)
|
||||
{
|
||||
return self->flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_release:
|
||||
* @self: a `GdkTexture` wrapping a GL texture
|
||||
@@ -295,7 +308,8 @@ gdk_gl_texture_release (GdkGLTexture *self)
|
||||
|
||||
texture = GDK_TEXTURE (self);
|
||||
self->saved = GDK_TEXTURE (gdk_memory_texture_from_texture (texture,
|
||||
gdk_texture_get_format (texture)));
|
||||
gdk_texture_get_format (texture),
|
||||
gdk_texture_get_color_space (texture)));
|
||||
|
||||
if (self->destroy)
|
||||
{
|
||||
@@ -428,6 +442,10 @@ gdk_gl_texture_determine_format (GdkGLTexture *self)
|
||||
* which will happen when the GdkTexture object is finalized, or due to
|
||||
* an explicit call of [method@Gdk.GLTexture.release].
|
||||
*
|
||||
* The texture data is assumed to be premultiplied, not flipped, and in the
|
||||
* sRGB colorspace, see [ctor@Gdk.GLTexture.new_with_color_profile] to override
|
||||
* this.
|
||||
*
|
||||
* Return value: (transfer full) (type GdkGLTexture): A newly-created
|
||||
* `GdkTexture`
|
||||
*/
|
||||
@@ -438,6 +456,46 @@ gdk_gl_texture_new (GdkGLContext *context,
|
||||
int height,
|
||||
GDestroyNotify destroy,
|
||||
gpointer data)
|
||||
{
|
||||
return gdk_gl_texture_new_with_color_space (context, id,
|
||||
width, height,
|
||||
GDK_GL_TEXTURE_PREMULTIPLIED,
|
||||
gdk_color_space_get_srgb (),
|
||||
destroy, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_new_with_color_space:
|
||||
* @context: a `GdkGLContext`
|
||||
* @id: the ID of a texture that was created with @context
|
||||
* @width: the nominal width of the texture
|
||||
* @height: the nominal height of the texture
|
||||
* @flags: flags that describe the content of the texture
|
||||
* @color_space: the `GdkColorSpace` for the content of the texture
|
||||
* @destroy: a destroy notify that will be called when the GL resources
|
||||
* are released
|
||||
* @data: data that gets passed to @destroy
|
||||
*
|
||||
* Creates a new texture for an existing GL texture with a given color space
|
||||
* and flags.
|
||||
*
|
||||
* Note that the GL texture must not be modified until @destroy is called,
|
||||
* which will happen when the `GdkTexture` object is finalized, or due to
|
||||
* an explicit call of [method@Gdk.GLTexture.release].
|
||||
*
|
||||
* Return value: (transfer full): A newly-created `GdkTexture`
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
GdkTexture *
|
||||
gdk_gl_texture_new_with_color_space (GdkGLContext *context,
|
||||
guint id,
|
||||
int width,
|
||||
int height,
|
||||
GdkGLTextureFlags flags,
|
||||
GdkColorSpace *color_space,
|
||||
GDestroyNotify destroy,
|
||||
gpointer data)
|
||||
{
|
||||
GdkGLTexture *self;
|
||||
|
||||
@@ -449,10 +507,12 @@ gdk_gl_texture_new (GdkGLContext *context,
|
||||
self = g_object_new (GDK_TYPE_GL_TEXTURE,
|
||||
"width", width,
|
||||
"height", height,
|
||||
"color-space", color_space,
|
||||
NULL);
|
||||
|
||||
self->context = g_object_ref (context);
|
||||
self->id = id;
|
||||
self->flags = flags;
|
||||
self->destroy = destroy;
|
||||
self->data = data;
|
||||
|
||||
@@ -460,4 +520,3 @@ gdk_gl_texture_new (GdkGLContext *context,
|
||||
|
||||
return GDK_TEXTURE (self);
|
||||
}
|
||||
|
||||
|
@@ -47,6 +47,29 @@ GdkTexture * gdk_gl_texture_new (GdkGLContext
|
||||
GDestroyNotify destroy,
|
||||
gpointer data);
|
||||
|
||||
/**
|
||||
* GdkGLTextureFlags:
|
||||
* @GDK_GL_TEXTURE_FLAGS_PREMULTIPLIED: The alpha in the data is premultiplied
|
||||
* @GDK_GL_TEXTURE_FLAGS_FLIPPED: The data has the origin at the bottom (this is usually
|
||||
* th case for textures that are produced by GL rendering)
|
||||
*
|
||||
* Flags that describe the content of a GL texture.
|
||||
*/
|
||||
typedef enum {
|
||||
GDK_GL_TEXTURE_PREMULTIPLIED = 1 << 0,
|
||||
GDK_GL_TEXTURE_FLIPPED = 1 << 1,
|
||||
} GdkGLTextureFlags;
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GdkTexture * gdk_gl_texture_new_with_color_space (GdkGLContext *context,
|
||||
guint id,
|
||||
int width,
|
||||
int height,
|
||||
GdkGLTextureFlags flags,
|
||||
GdkColorSpace *color_space,
|
||||
GDestroyNotify destroy,
|
||||
gpointer data);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_gl_texture_release (GdkGLTexture *self);
|
||||
|
||||
|
@@ -9,6 +9,7 @@ G_BEGIN_DECLS
|
||||
|
||||
GdkGLContext * gdk_gl_texture_get_context (GdkGLTexture *self);
|
||||
guint gdk_gl_texture_get_id (GdkGLTexture *self);
|
||||
GdkGLTextureFlags gdk_gl_texture_get_flags (GdkGLTexture *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
342
gdk/gdklcmscolorspace.c
Normal file
@@ -0,0 +1,342 @@
|
||||
/* gdklcmscolorspace.c
|
||||
*
|
||||
* Copyright 2021 (c) Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 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 "gdklcmscolorspaceprivate.h"
|
||||
#include "gdkcicpcolorspaceprivate.h"
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
struct _GdkLcmsColorSpace
|
||||
{
|
||||
GdkColorSpace parent_instance;
|
||||
|
||||
cmsHPROFILE lcms_profile;
|
||||
};
|
||||
|
||||
struct _GdkLcmsColorSpaceClass
|
||||
{
|
||||
GdkColorSpaceClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GdkLcmsColorSpace, gdk_lcms_color_space, GDK_TYPE_COLOR_SPACE)
|
||||
|
||||
static gboolean
|
||||
gdk_lcms_color_space_supports_format (GdkColorSpace *space,
|
||||
GdkMemoryFormat format)
|
||||
{
|
||||
GdkLcmsColorSpace *self = GDK_LCMS_COLOR_SPACE (space);
|
||||
|
||||
return cmsGetColorSpace (self->lcms_profile) == cmsSigRgbData;
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
gdk_lcms_color_space_save_to_icc_profile (GdkColorSpace *space,
|
||||
GError **error)
|
||||
{
|
||||
GdkLcmsColorSpace *self = GDK_LCMS_COLOR_SPACE (space);
|
||||
cmsUInt32Number size;
|
||||
guchar *data;
|
||||
|
||||
size = 0;
|
||||
if (!cmsSaveProfileToMem (self->lcms_profile, NULL, &size))
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Could not prepare ICC profile"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data = g_malloc (size);
|
||||
if (!cmsSaveProfileToMem (self->lcms_profile, data, &size))
|
||||
{
|
||||
g_free (data);
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Failed to save ICC profile"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return g_bytes_new_take (data, size);
|
||||
}
|
||||
|
||||
static int
|
||||
gdk_lcms_color_space_get_n_components (GdkColorSpace *space)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_lcms_color_space_equal (GdkColorSpace *profile1,
|
||||
GdkColorSpace *profile2)
|
||||
{
|
||||
GBytes *icc1, *icc2;
|
||||
gboolean res;
|
||||
|
||||
icc1 = gdk_color_space_save_to_icc_profile (profile1, NULL);
|
||||
icc2 = gdk_color_space_save_to_icc_profile (profile2, NULL);
|
||||
|
||||
res = g_bytes_equal (icc1, icc2);
|
||||
|
||||
g_bytes_unref (icc1);
|
||||
g_bytes_unref (icc2);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_lcms_color_space_dispose (GObject *object)
|
||||
{
|
||||
GdkLcmsColorSpace *self = GDK_LCMS_COLOR_SPACE (object);
|
||||
|
||||
g_clear_pointer (&self->lcms_profile, cmsCloseProfile);
|
||||
|
||||
G_OBJECT_CLASS (gdk_lcms_color_space_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_lcms_color_space_class_init (GdkLcmsColorSpaceClass *klass)
|
||||
{
|
||||
GdkColorSpaceClass *color_space_class = GDK_COLOR_SPACE_CLASS (klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
color_space_class->supports_format = gdk_lcms_color_space_supports_format;
|
||||
color_space_class->save_to_icc_profile = gdk_lcms_color_space_save_to_icc_profile;
|
||||
color_space_class->get_n_components = gdk_lcms_color_space_get_n_components;
|
||||
color_space_class->equal = gdk_lcms_color_space_equal;
|
||||
|
||||
gobject_class->dispose = gdk_lcms_color_space_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_lcms_color_space_init (GdkLcmsColorSpace *self)
|
||||
{
|
||||
}
|
||||
|
||||
GdkColorSpace *
|
||||
gdk_lcms_color_space_new_from_lcms_profile (cmsHPROFILE lcms_profile)
|
||||
{
|
||||
GdkLcmsColorSpace *result;
|
||||
|
||||
result = g_object_new (GDK_TYPE_LCMS_COLOR_SPACE, NULL);
|
||||
result->lcms_profile = lcms_profile;
|
||||
|
||||
return GDK_COLOR_SPACE (result);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_color_space_new_from_icc_profile:
|
||||
* @icc_profile: The ICC profiles given as a `GBytes`
|
||||
* @error: Return location for an error
|
||||
*
|
||||
* Creates a new color profile for the given ICC profile data.
|
||||
*
|
||||
* if the profile is not valid, %NULL is returned and an error
|
||||
* is raised.
|
||||
*
|
||||
* Returns: a new `GdkLcmsColorSpace` or %NULL on error
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
GdkColorSpace *
|
||||
gdk_color_space_new_from_icc_profile (GBytes *icc_profile,
|
||||
GError **error)
|
||||
{
|
||||
cmsHPROFILE lcms_profile;
|
||||
const guchar *data;
|
||||
gsize size;
|
||||
|
||||
g_return_val_if_fail (icc_profile != NULL, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
data = g_bytes_get_data (icc_profile, &size);
|
||||
|
||||
lcms_profile = cmsOpenProfileFromMem (data, size);
|
||||
if (lcms_profile == NULL)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Failed to load ICC profile"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return gdk_lcms_color_space_new_from_lcms_profile (lcms_profile);
|
||||
}
|
||||
|
||||
cmsHPROFILE
|
||||
gdk_lcms_color_space_get_lcms_profile (GdkColorSpace *self)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_LCMS_COLOR_SPACE (self), NULL);
|
||||
|
||||
return GDK_LCMS_COLOR_SPACE (self)->lcms_profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_color_space_get_srgb:
|
||||
*
|
||||
* Returns the object representing the sRGB color space.
|
||||
*
|
||||
* If you don't know anything about color spaces but need one for
|
||||
* use with some function, this one is most likely the right one.
|
||||
*
|
||||
* Returns: (transfer none): the object for the sRGB color space.
|
||||
*
|
||||
* Since: 4.8
|
||||
*/
|
||||
GdkColorSpace *
|
||||
gdk_color_space_get_srgb (void)
|
||||
{
|
||||
static GdkColorSpace *srgb_color_space;
|
||||
|
||||
if (g_once_init_enter (&srgb_color_space))
|
||||
{
|
||||
GdkColorSpace *color_space;
|
||||
|
||||
color_space = gdk_lcms_color_space_new_from_lcms_profile (cmsCreate_sRGBProfile ());
|
||||
g_assert (color_space);
|
||||
|
||||
g_once_init_leave (&srgb_color_space, color_space);
|
||||
}
|
||||
|
||||
return srgb_color_space;
|
||||
}
|
||||
|
||||
/*<private>
|
||||
* gdk_color_space_get_srgb_linear:
|
||||
*
|
||||
* Returns the object corresponding to the linear sRGB color space.
|
||||
*
|
||||
* It can display the same colors as the sRGB color space, but it
|
||||
* does not have a gamma curve.
|
||||
*
|
||||
* Returns: (transfer none): the object for the linear sRGB color space.
|
||||
*
|
||||
* Since: 4.8
|
||||
*/
|
||||
GdkColorSpace *
|
||||
gdk_color_space_get_srgb_linear (void)
|
||||
{
|
||||
static GdkColorSpace *srgb_linear_color_space;
|
||||
|
||||
if (g_once_init_enter (&srgb_linear_color_space))
|
||||
{
|
||||
cmsToneCurve *curve;
|
||||
cmsHPROFILE lcms_profile;
|
||||
GdkColorSpace *color_space;
|
||||
|
||||
curve = cmsBuildGamma (NULL, 1.0);
|
||||
lcms_profile = cmsCreateRGBProfile (&(cmsCIExyY) {
|
||||
0.3127, 0.3290, 1.0
|
||||
},
|
||||
&(cmsCIExyYTRIPLE) {
|
||||
{ 0.6400, 0.3300, 1.0 },
|
||||
{ 0.3000, 0.6000, 1.0 },
|
||||
{ 0.1500, 0.0600, 1.0 }
|
||||
},
|
||||
(cmsToneCurve*[3]) { curve, curve, curve });
|
||||
cmsFreeToneCurve (curve);
|
||||
|
||||
color_space = gdk_lcms_color_space_new_from_lcms_profile (lcms_profile);
|
||||
g_assert (color_space);
|
||||
|
||||
g_once_init_leave (&srgb_linear_color_space, color_space);
|
||||
}
|
||||
|
||||
return srgb_linear_color_space;
|
||||
}
|
||||
|
||||
typedef struct _GdkColorTransformCache GdkColorTransformCache;
|
||||
|
||||
struct _GdkColorTransformCache
|
||||
{
|
||||
GdkColorSpace *source;
|
||||
guint source_type;
|
||||
GdkColorSpace *dest;
|
||||
guint dest_type;
|
||||
};
|
||||
|
||||
static void
|
||||
gdk_color_transform_cache_free (gpointer data)
|
||||
{
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static guint
|
||||
gdk_color_transform_cache_hash (gconstpointer data)
|
||||
{
|
||||
const GdkColorTransformCache *cache = data;
|
||||
|
||||
return g_direct_hash (cache->source) ^
|
||||
(g_direct_hash (cache->dest) >> 2) ^
|
||||
((cache->source_type << 16) | (cache->source_type >> 16)) ^
|
||||
cache->dest_type;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_color_transform_cache_equal (gconstpointer data1,
|
||||
gconstpointer data2)
|
||||
{
|
||||
const GdkColorTransformCache *cache1 = data1;
|
||||
const GdkColorTransformCache *cache2 = data2;
|
||||
|
||||
return cache1->source == cache2->source &&
|
||||
cache1->source_type == cache2->source_type &&
|
||||
cache1->dest == cache2->dest &&
|
||||
cache1->dest_type == cache2->dest_type;
|
||||
}
|
||||
|
||||
cmsHTRANSFORM *
|
||||
gdk_color_space_lookup_transform (GdkColorSpace *source,
|
||||
guint source_type,
|
||||
GdkColorSpace *dest,
|
||||
guint dest_type)
|
||||
{
|
||||
GdkColorTransformCache *entry;
|
||||
static GHashTable *cache = NULL;
|
||||
cmsHTRANSFORM *transform;
|
||||
|
||||
if (GDK_IS_CICP_COLOR_SPACE (dest))
|
||||
dest = gdk_cicp_color_space_get_lcms_color_space (dest);
|
||||
|
||||
if (GDK_IS_CICP_COLOR_SPACE (source))
|
||||
source = gdk_cicp_color_space_get_lcms_color_space (source);
|
||||
|
||||
if (cache == NULL)
|
||||
cache = g_hash_table_new_full (gdk_color_transform_cache_hash,
|
||||
gdk_color_transform_cache_equal,
|
||||
gdk_color_transform_cache_free,
|
||||
cmsDeleteTransform);
|
||||
|
||||
transform = g_hash_table_lookup (cache,
|
||||
&(GdkColorTransformCache) {
|
||||
source, source_type,
|
||||
dest, dest_type
|
||||
});
|
||||
if (G_UNLIKELY (transform == NULL && source && dest))
|
||||
{
|
||||
transform = cmsCreateTransform (gdk_lcms_color_space_get_lcms_profile (source),
|
||||
source_type,
|
||||
gdk_lcms_color_space_get_lcms_profile (dest),
|
||||
dest_type,
|
||||
INTENT_PERCEPTUAL,
|
||||
cmsFLAGS_COPY_ALPHA);
|
||||
entry = g_new (GdkColorTransformCache, 1);
|
||||
*entry = (GdkColorTransformCache) {
|
||||
source, source_type,
|
||||
dest, dest_type
|
||||
};
|
||||
g_hash_table_insert (cache, entry, transform);
|
||||
}
|
||||
|
||||
return transform;
|
||||
}
|
48
gdk/gdklcmscolorspaceprivate.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/* gdklcmscolorspace.h
|
||||
*
|
||||
* Copyright 2021 (c) Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_LCMS_COLOR_SPACE_PRIVATE_H__
|
||||
#define __GDK_LCMS_COLOR_SPACE_PRIVATE_H__
|
||||
|
||||
#include "gdkcolorspaceprivate.h"
|
||||
|
||||
#include <lcms2.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_LCMS_COLOR_SPACE (gdk_lcms_color_space_get_type ())
|
||||
|
||||
#define GDK_LCMS_COLOR_SPACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_LCMS_COLOR_SPACE, GdkLcmsColorSpace))
|
||||
#define GDK_IS_LCMS_COLOR_SPACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_LCMS_COLOR_SPACE))
|
||||
#define GDK_LCMS_COLOR_SPACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_LCMS_COLOR_SPACE, GdkLcmsColorSpaceClass))
|
||||
#define GDK_IS_LCMS_COLOR_SPACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_LCMS_COLOR_SPACE))
|
||||
#define GDK_LCMS_COLOR_SPACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_LCMS_COLOR_SPACE, GdkLcmsColorSpaceClass))
|
||||
|
||||
typedef struct _GdkLcmsColorSpace GdkLcmsColorSpace;
|
||||
typedef struct _GdkLcmsColorSpaceClass GdkLcmsColorSpaceClass;
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkLcmsColorSpace, g_object_unref)
|
||||
|
||||
GType gdk_lcms_color_space_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GdkColorSpace * gdk_lcms_color_space_new_from_lcms_profile (cmsHPROFILE lcms_profile);
|
||||
cmsHPROFILE gdk_lcms_color_space_get_lcms_profile (GdkColorSpace *color_space);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_LCMS_COLOR_SPACE_PRIVATE_H__ */
|
@@ -21,6 +21,9 @@
|
||||
|
||||
#include "gdkmemoryformatprivate.h"
|
||||
|
||||
#include "gdklcmscolorspaceprivate.h"
|
||||
#include "gdkcicpcolorspaceprivate.h"
|
||||
#include "gdkprofilerprivate.h"
|
||||
#include "gsk/gl/fp16private.h"
|
||||
|
||||
#include <epoxy/gl.h>
|
||||
@@ -72,6 +75,223 @@ TYPED_FUNCS (b8g8r8, guchar, 2, 1, 0, -1, 3, 255)
|
||||
TYPED_FUNCS (r16g16b16, guint16, 0, 1, 2, -1, 6, 65535)
|
||||
TYPED_FUNCS (r16g16b16a16, guint16, 0, 1, 2, 3, 8, 65535)
|
||||
|
||||
#define PREMULTIPLY_FUNCS(type, A, scale) \
|
||||
static void \
|
||||
type ## _premultiply_ ## A (guchar *dest_data, \
|
||||
const guchar *src_data, \
|
||||
gsize n) \
|
||||
{ \
|
||||
type *dest = (type *) dest_data; \
|
||||
const type *src = (const type *) src_data; \
|
||||
for (gsize i = 0; i < n; i++) \
|
||||
{ \
|
||||
unsigned a = src[A]; \
|
||||
if (A != 0) dest[0] = src[0] * a / scale; \
|
||||
if (A != 1) dest[1] = src[1] * a / scale; \
|
||||
if (A != 2) dest[2] = src[2] * a / scale; \
|
||||
if (A != 3) dest[3] = src[3] * a / scale; \
|
||||
dest[A] = a; \
|
||||
src += 4; \
|
||||
dest += 4; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static void \
|
||||
type ## _unpremultiply_ ## A (guchar *dest_data, \
|
||||
const guchar *src_data, \
|
||||
gsize n) \
|
||||
{ \
|
||||
type *dest = (type *) dest_data; \
|
||||
const type *src = (const type *) src_data; \
|
||||
for (gsize i = 0; i < n; i++) \
|
||||
{ \
|
||||
unsigned a = src[A]; \
|
||||
if (a == 0) \
|
||||
{ \
|
||||
dest[0] = dest[1] = dest[2] = dest[3] = 0; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
if (A != 0) dest[0] = (src[0] * scale + a / 2) / a; \
|
||||
if (A != 1) dest[1] = (src[1] * scale + a / 2) / a; \
|
||||
if (A != 2) dest[2] = (src[2] * scale + a / 2) / a; \
|
||||
if (A != 3) dest[3] = (src[3] * scale + a / 2) / a; \
|
||||
dest[A] = a; \
|
||||
} \
|
||||
src += 4; \
|
||||
dest += 4; \
|
||||
} \
|
||||
}
|
||||
|
||||
PREMULTIPLY_FUNCS (guint8, 0, G_MAXUINT8)
|
||||
PREMULTIPLY_FUNCS (guint8, 3, G_MAXUINT8)
|
||||
PREMULTIPLY_FUNCS (guint16, 3, G_MAXUINT16)
|
||||
|
||||
static void
|
||||
half_float_premultiply (guchar *dest_data,
|
||||
const guchar *src_data,
|
||||
gsize n)
|
||||
{
|
||||
guint16 *dest = (guint16 *) dest_data;
|
||||
const float *src = (const float *) src_data;
|
||||
for (gsize i = 0; i < n; i++)
|
||||
{
|
||||
float tmp[4];
|
||||
tmp[0] = src[0] * src[3];
|
||||
tmp[1] = src[1] * src[3];
|
||||
tmp[2] = src[2] * src[3];
|
||||
tmp[3] = src[3];
|
||||
float_to_half4 (tmp, dest);
|
||||
dest += 4;
|
||||
src += 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
half_float_unpremultiply (guchar *dest_data,
|
||||
const guchar *src_data,
|
||||
gsize n)
|
||||
{
|
||||
float *dest = (float *) dest_data;
|
||||
const guint16 *src = (const guint16 *) src_data;
|
||||
for (gsize i = 0; i < n; i++)
|
||||
{
|
||||
half_to_float4 (src, dest);
|
||||
if (dest[3] <= 1/255.0)
|
||||
{
|
||||
memset (dest, 0, sizeof (guint) * 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
dest[0] = dest[0] / dest[3];
|
||||
dest[1] = dest[1] / dest[3];
|
||||
dest[2] = dest[2] / dest[3];
|
||||
}
|
||||
dest += 4;
|
||||
src += 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
float_premultiply (guchar *dest_data,
|
||||
const guchar *src_data,
|
||||
gsize n)
|
||||
{
|
||||
float *dest = (float *) dest_data;
|
||||
const float *src = (const float *) src_data;
|
||||
for (gsize i = 0; i < n; i++)
|
||||
{
|
||||
float a = src[3];
|
||||
dest[0] = src[0] * a;
|
||||
dest[1] = src[1] * a;
|
||||
dest[2] = src[2] * a;
|
||||
dest[3] = a;
|
||||
dest += 4;
|
||||
src += 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
float_unpremultiply (guchar *dest_data,
|
||||
const guchar *src_data,
|
||||
gsize n)
|
||||
{
|
||||
float *dest = (float *) dest_data;
|
||||
const float *src = (const float *) src_data;
|
||||
for (gsize i = 0; i < n; i++)
|
||||
{
|
||||
float a = src[3];
|
||||
if (a <= 1/255.0)
|
||||
{
|
||||
memset (dest, 0, sizeof (float) * 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
dest[0] = src[0] / a;
|
||||
dest[1] = src[1] / a;
|
||||
dest[2] = src[2] / a;
|
||||
dest[3] = a;
|
||||
}
|
||||
dest += 4;
|
||||
src += 4;
|
||||
}
|
||||
}
|
||||
|
||||
#define COMPRESS_FUNCS(type, scale) \
|
||||
static void \
|
||||
type ## _expand (guchar *dest_data, \
|
||||
const guchar *src_data, \
|
||||
gsize n) \
|
||||
{ \
|
||||
type *dest = (type *) dest_data; \
|
||||
const type *src = (const type *) src_data; \
|
||||
for (gsize i = 0; i < n; i++) \
|
||||
{ \
|
||||
dest[0] = src[0]; \
|
||||
dest[1] = src[1]; \
|
||||
dest[2] = src[2]; \
|
||||
dest[3] = scale; \
|
||||
dest += 4; \
|
||||
src += 3; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static void \
|
||||
type ## _compress (guchar *dest_data, \
|
||||
const guchar *src_data, \
|
||||
gsize n) \
|
||||
{ \
|
||||
type *dest = (type *) dest_data; \
|
||||
const type *src = (const type *) src_data; \
|
||||
for (gsize i = 0; i < n; i++) \
|
||||
{ \
|
||||
dest[0] = src[0] * src[3] / scale; \
|
||||
dest[1] = src[1] * src[3] / scale; \
|
||||
dest[2] = src[2] * src[3] / scale; \
|
||||
dest += 3; \
|
||||
src += 4; \
|
||||
} \
|
||||
}
|
||||
|
||||
COMPRESS_FUNCS (guint8, G_MAXUINT8)
|
||||
COMPRESS_FUNCS (guint16, G_MAXUINT16)
|
||||
COMPRESS_FUNCS (float, 1.0f)
|
||||
|
||||
static void
|
||||
half_float_expand (guchar *dest_data,
|
||||
const guchar *src_data,
|
||||
gsize n)
|
||||
{
|
||||
float *dest = (float *) dest_data;
|
||||
const guint16 *src = (const guint16 *) src_data;
|
||||
for (gsize i = 0; i < n; i++)
|
||||
{
|
||||
half_to_float (src, dest, 3);
|
||||
dest[3] = 1.0;
|
||||
dest += 4;
|
||||
src += 3;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
half_float_compress (guchar *dest_data,
|
||||
const guchar *src_data,
|
||||
gsize n)
|
||||
{
|
||||
guint16 *dest = (guint16 *) dest_data;
|
||||
const float *src = (const float *) src_data;
|
||||
for (gsize i = 0; i < n; i++)
|
||||
{
|
||||
float tmp[3];
|
||||
tmp[0] = src[0] * src[3];
|
||||
tmp[1] = src[1] * src[3];
|
||||
tmp[2] = src[2] * src[3];
|
||||
float_to_half (tmp, dest, 3);
|
||||
dest += 3;
|
||||
src += 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
r16g16b16_float_to_float (float *dest,
|
||||
const guchar *src_data,
|
||||
@@ -166,56 +386,9 @@ r32g32b32a32_float_from_float (guchar *dest,
|
||||
memcpy (dest, src, sizeof (float) * n * 4);
|
||||
}
|
||||
|
||||
#define PREMULTIPLY_FUNC(name, R1, G1, B1, A1, R2, G2, B2, A2) \
|
||||
static void \
|
||||
name (guchar *dest, \
|
||||
const guchar *src, \
|
||||
gsize n) \
|
||||
{ \
|
||||
for (; n > 0; n--) \
|
||||
{ \
|
||||
guchar a = src[A1]; \
|
||||
guint16 r = (guint16)src[R1] * a + 127; \
|
||||
guint16 g = (guint16)src[G1] * a + 127; \
|
||||
guint16 b = (guint16)src[B1] * a + 127; \
|
||||
dest[R2] = (r + (r >> 8) + 1) >> 8; \
|
||||
dest[G2] = (g + (g >> 8) + 1) >> 8; \
|
||||
dest[B2] = (b + (b >> 8) + 1) >> 8; \
|
||||
dest[A2] = a; \
|
||||
dest += 4; \
|
||||
src += 4; \
|
||||
} \
|
||||
}
|
||||
|
||||
PREMULTIPLY_FUNC(r8g8b8a8_to_r8g8b8a8_premultiplied, 0, 1, 2, 3, 0, 1, 2, 3)
|
||||
PREMULTIPLY_FUNC(r8g8b8a8_to_b8g8r8a8_premultiplied, 0, 1, 2, 3, 2, 1, 0, 3)
|
||||
PREMULTIPLY_FUNC(r8g8b8a8_to_a8r8g8b8_premultiplied, 0, 1, 2, 3, 1, 2, 3, 0)
|
||||
PREMULTIPLY_FUNC(r8g8b8a8_to_a8b8g8r8_premultiplied, 0, 1, 2, 3, 3, 2, 1, 0)
|
||||
|
||||
#define ADD_ALPHA_FUNC(name, R1, G1, B1, R2, G2, B2, A2) \
|
||||
static void \
|
||||
name (guchar *dest, \
|
||||
const guchar *src, \
|
||||
gsize n) \
|
||||
{ \
|
||||
for (; n > 0; n--) \
|
||||
{ \
|
||||
dest[R2] = src[R1]; \
|
||||
dest[G2] = src[G1]; \
|
||||
dest[B2] = src[B1]; \
|
||||
dest[A2] = 255; \
|
||||
dest += 4; \
|
||||
src += 3; \
|
||||
} \
|
||||
}
|
||||
|
||||
ADD_ALPHA_FUNC(r8g8b8_to_r8g8b8a8, 0, 1, 2, 0, 1, 2, 3)
|
||||
ADD_ALPHA_FUNC(r8g8b8_to_b8g8r8a8, 0, 1, 2, 2, 1, 0, 3)
|
||||
ADD_ALPHA_FUNC(r8g8b8_to_a8r8g8b8, 0, 1, 2, 1, 2, 3, 0)
|
||||
ADD_ALPHA_FUNC(r8g8b8_to_a8b8g8r8, 0, 1, 2, 3, 2, 1, 0)
|
||||
|
||||
struct _GdkMemoryFormatDescription
|
||||
{
|
||||
const char *name;
|
||||
GdkMemoryAlpha alpha;
|
||||
gsize bytes_per_pixel;
|
||||
gsize alignment;
|
||||
@@ -229,6 +402,12 @@ struct _GdkMemoryFormatDescription
|
||||
/* no premultiplication going on here */
|
||||
void (* to_float) (float *, const guchar*, gsize);
|
||||
void (* from_float) (guchar *, const float *, gsize);
|
||||
struct {
|
||||
guint type;
|
||||
gsize bpp;
|
||||
} lcms;
|
||||
void (* to_lcms) (guchar *, const guchar *, gsize);
|
||||
void (* from_lcms) (guchar *, const guchar *, gsize);
|
||||
};
|
||||
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
@@ -241,6 +420,7 @@ struct _GdkMemoryFormatDescription
|
||||
|
||||
static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
[GDK_MEMORY_B8G8R8A8_PREMULTIPLIED] = {
|
||||
"B8G8R8A8_PREMULTIPLIED",
|
||||
GDK_MEMORY_ALPHA_PREMULTIPLIED,
|
||||
4,
|
||||
G_ALIGNOF (guchar),
|
||||
@@ -249,8 +429,12 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
{ GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE },
|
||||
b8g8r8a8_premultiplied_to_float,
|
||||
b8g8r8a8_premultiplied_from_float,
|
||||
{ TYPE_BGRA_8, 4 },
|
||||
guint8_unpremultiply_3,
|
||||
guint8_premultiply_3,
|
||||
},
|
||||
[GDK_MEMORY_A8R8G8B8_PREMULTIPLIED] = {
|
||||
"A8R8G8B8_PREMULTIPLIED",
|
||||
GDK_MEMORY_ALPHA_PREMULTIPLIED,
|
||||
4,
|
||||
G_ALIGNOF (guchar),
|
||||
@@ -259,8 +443,12 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
{ GL_RGBA8, GL_BGRA, GDK_GL_UNSIGNED_BYTE_FLIPPED },
|
||||
a8r8g8b8_premultiplied_to_float,
|
||||
a8r8g8b8_premultiplied_from_float,
|
||||
{ TYPE_ARGB_8, 4 },
|
||||
guint8_unpremultiply_0,
|
||||
guint8_premultiply_0,
|
||||
},
|
||||
[GDK_MEMORY_R8G8B8A8_PREMULTIPLIED] = {
|
||||
"R8G8B8A8_PREMULTIPLIED",
|
||||
GDK_MEMORY_ALPHA_PREMULTIPLIED,
|
||||
4,
|
||||
G_ALIGNOF (guchar),
|
||||
@@ -269,8 +457,12 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE },
|
||||
r8g8b8a8_premultiplied_to_float,
|
||||
r8g8b8a8_premultiplied_from_float,
|
||||
{ TYPE_RGBA_8, 4 },
|
||||
guint8_unpremultiply_3,
|
||||
guint8_premultiply_3,
|
||||
},
|
||||
[GDK_MEMORY_B8G8R8A8] = {
|
||||
"B8G8R8A8",
|
||||
GDK_MEMORY_ALPHA_STRAIGHT,
|
||||
4,
|
||||
G_ALIGNOF (guchar),
|
||||
@@ -279,8 +471,12 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
{ GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE },
|
||||
b8g8r8a8_to_float,
|
||||
b8g8r8a8_from_float,
|
||||
{ TYPE_BGRA_8, 4 },
|
||||
NULL,
|
||||
NULL,
|
||||
},
|
||||
[GDK_MEMORY_A8R8G8B8] = {
|
||||
"A8R8G8B8",
|
||||
GDK_MEMORY_ALPHA_STRAIGHT,
|
||||
4,
|
||||
G_ALIGNOF (guchar),
|
||||
@@ -289,8 +485,12 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
{ GL_RGBA8, GL_RGBA, GDK_GL_UNSIGNED_BYTE_FLIPPED },
|
||||
a8r8g8b8_to_float,
|
||||
a8r8g8b8_from_float,
|
||||
{ TYPE_ARGB_8, 4 },
|
||||
NULL,
|
||||
NULL,
|
||||
},
|
||||
[GDK_MEMORY_R8G8B8A8] = {
|
||||
"R8G8B8A8",
|
||||
GDK_MEMORY_ALPHA_STRAIGHT,
|
||||
4,
|
||||
G_ALIGNOF (guchar),
|
||||
@@ -299,8 +499,12 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE },
|
||||
r8g8b8a8_to_float,
|
||||
r8g8b8a8_from_float,
|
||||
{ TYPE_RGBA_8, 4 },
|
||||
NULL,
|
||||
NULL,
|
||||
},
|
||||
[GDK_MEMORY_A8B8G8R8] = {
|
||||
"A8B8G8R8",
|
||||
GDK_MEMORY_ALPHA_STRAIGHT,
|
||||
4,
|
||||
G_ALIGNOF (guchar),
|
||||
@@ -309,8 +513,12 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
{ GL_RGBA8, GL_BGRA, GDK_GL_UNSIGNED_BYTE_FLIPPED },
|
||||
a8b8g8r8_to_float,
|
||||
a8b8g8r8_from_float,
|
||||
{ TYPE_ABGR_8, 4 },
|
||||
NULL,
|
||||
NULL,
|
||||
},
|
||||
[GDK_MEMORY_R8G8B8] = {
|
||||
"R8G8B8",
|
||||
GDK_MEMORY_ALPHA_OPAQUE,
|
||||
3,
|
||||
G_ALIGNOF (guchar),
|
||||
@@ -319,8 +527,12 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
{ GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE },
|
||||
r8g8b8_to_float,
|
||||
r8g8b8_from_float,
|
||||
{ TYPE_RGBA_8, 4 },
|
||||
guint8_expand,
|
||||
guint8_compress,
|
||||
},
|
||||
[GDK_MEMORY_B8G8R8] = {
|
||||
"B8G8R8",
|
||||
GDK_MEMORY_ALPHA_OPAQUE,
|
||||
3,
|
||||
G_ALIGNOF (guchar),
|
||||
@@ -329,8 +541,12 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
{ GL_RGB8, GL_BGR, GL_UNSIGNED_BYTE },
|
||||
b8g8r8_to_float,
|
||||
b8g8r8_from_float,
|
||||
{ TYPE_BGRA_8, 4 },
|
||||
guint8_expand,
|
||||
guint8_compress,
|
||||
},
|
||||
[GDK_MEMORY_R16G16B16] = {
|
||||
"R16G16B16",
|
||||
GDK_MEMORY_ALPHA_OPAQUE,
|
||||
6,
|
||||
G_ALIGNOF (guint16),
|
||||
@@ -339,8 +555,12 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
{ GL_RGB16, GL_RGB, GL_UNSIGNED_SHORT },
|
||||
r16g16b16_to_float,
|
||||
r16g16b16_from_float,
|
||||
{ TYPE_RGBA_16, 8 },
|
||||
guint16_expand,
|
||||
guint16_compress,
|
||||
},
|
||||
[GDK_MEMORY_R16G16B16A16_PREMULTIPLIED] = {
|
||||
"R16G16B16A16_PREMULTIPLIED",
|
||||
GDK_MEMORY_ALPHA_PREMULTIPLIED,
|
||||
8,
|
||||
G_ALIGNOF (guint16),
|
||||
@@ -349,8 +569,12 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
{ GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT },
|
||||
r16g16b16a16_to_float,
|
||||
r16g16b16a16_from_float,
|
||||
{ TYPE_RGBA_16, 8 },
|
||||
guint16_unpremultiply_3,
|
||||
guint16_premultiply_3,
|
||||
},
|
||||
[GDK_MEMORY_R16G16B16A16] = {
|
||||
"R16G16B16A16",
|
||||
GDK_MEMORY_ALPHA_STRAIGHT,
|
||||
8,
|
||||
G_ALIGNOF (guint16),
|
||||
@@ -359,8 +583,12 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
{ GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT },
|
||||
r16g16b16a16_to_float,
|
||||
r16g16b16a16_from_float,
|
||||
{ TYPE_RGBA_16, 8 },
|
||||
NULL,
|
||||
NULL,
|
||||
},
|
||||
[GDK_MEMORY_R16G16B16_FLOAT] = {
|
||||
"R16G16B16_FLOAT",
|
||||
GDK_MEMORY_ALPHA_OPAQUE,
|
||||
6,
|
||||
G_ALIGNOF (guint16),
|
||||
@@ -369,8 +597,12 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
{ GL_RGB16F, GL_RGB, GL_HALF_FLOAT },
|
||||
r16g16b16_float_to_float,
|
||||
r16g16b16_float_from_float,
|
||||
{ TYPE_RGBA_FLT, 16 },
|
||||
half_float_expand,
|
||||
half_float_compress,
|
||||
},
|
||||
[GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] = {
|
||||
"R16G16B16A16_FLOAT_PREMULTIPLIED",
|
||||
GDK_MEMORY_ALPHA_PREMULTIPLIED,
|
||||
8,
|
||||
G_ALIGNOF (guint16),
|
||||
@@ -379,8 +611,12 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
{ GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT },
|
||||
r16g16b16a16_float_to_float,
|
||||
r16g16b16a16_float_from_float,
|
||||
{ TYPE_RGBA_FLT, 16 },
|
||||
half_float_unpremultiply,
|
||||
half_float_premultiply,
|
||||
},
|
||||
[GDK_MEMORY_R16G16B16A16_FLOAT] = {
|
||||
"R16G16B16A16_FLOAT",
|
||||
GDK_MEMORY_ALPHA_STRAIGHT,
|
||||
8,
|
||||
G_ALIGNOF (guint16),
|
||||
@@ -389,8 +625,12 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
{ GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT },
|
||||
r16g16b16a16_float_to_float,
|
||||
r16g16b16a16_float_from_float,
|
||||
{ TYPE_RGBA_FLT, 16 },
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
[GDK_MEMORY_R32G32B32_FLOAT] = {
|
||||
"R32G32B32_FLOAT",
|
||||
GDK_MEMORY_ALPHA_OPAQUE,
|
||||
12,
|
||||
G_ALIGNOF (float),
|
||||
@@ -399,8 +639,12 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
{ GL_RGB32F, GL_RGB, GL_FLOAT },
|
||||
r32g32b32_float_to_float,
|
||||
r32g32b32_float_from_float,
|
||||
{ TYPE_RGBA_FLT, 16 },
|
||||
float_expand,
|
||||
float_compress,
|
||||
},
|
||||
[GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] = {
|
||||
"R32G32B32A32_FLOAT_PREMULTIPLIED",
|
||||
GDK_MEMORY_ALPHA_PREMULTIPLIED,
|
||||
16,
|
||||
G_ALIGNOF (float),
|
||||
@@ -409,8 +653,12 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
{ GL_RGBA32F, GL_RGBA, GL_FLOAT },
|
||||
r32g32b32a32_float_to_float,
|
||||
r32g32b32a32_float_from_float,
|
||||
{ TYPE_RGBA_FLT, 16 },
|
||||
float_unpremultiply,
|
||||
float_premultiply,
|
||||
},
|
||||
[GDK_MEMORY_R32G32B32A32_FLOAT] = {
|
||||
"R32G32B32A32_FLOAT",
|
||||
GDK_MEMORY_ALPHA_STRAIGHT,
|
||||
16,
|
||||
G_ALIGNOF (float),
|
||||
@@ -419,6 +667,9 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
{ GL_RGBA32F, GL_RGBA, GL_FLOAT },
|
||||
r32g32b32a32_float_to_float,
|
||||
r32g32b32a32_float_from_float,
|
||||
{ TYPE_RGBA_FLT, 16 },
|
||||
NULL,
|
||||
NULL,
|
||||
}
|
||||
};
|
||||
|
||||
@@ -509,86 +760,164 @@ unpremultiply (float *rgba,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gdk_memory_convert (guchar *dest_data,
|
||||
gsize dest_stride,
|
||||
GdkMemoryFormat dest_format,
|
||||
const guchar *src_data,
|
||||
gsize src_stride,
|
||||
GdkMemoryFormat src_format,
|
||||
gsize width,
|
||||
gsize height)
|
||||
static void
|
||||
gdk_memory_convert_same_format (guchar *dest_data,
|
||||
gsize dest_stride,
|
||||
const guchar *src_data,
|
||||
gsize src_stride,
|
||||
gsize width,
|
||||
gsize height,
|
||||
GdkMemoryFormat format)
|
||||
{
|
||||
const GdkMemoryFormatDescription *dest_desc = &memory_formats[dest_format];
|
||||
const GdkMemoryFormatDescription *src_desc = &memory_formats[src_format];
|
||||
float *tmp;
|
||||
gsize y;
|
||||
void (*func) (guchar *, const guchar *, gsize) = NULL;
|
||||
const GdkMemoryFormatDescription *desc = &memory_formats[format];
|
||||
gsize y, stride;
|
||||
|
||||
g_assert (dest_format < GDK_MEMORY_N_FORMATS);
|
||||
g_assert (src_format < GDK_MEMORY_N_FORMATS);
|
||||
|
||||
if (src_format == GDK_MEMORY_R8G8B8A8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
|
||||
func = r8g8b8a8_to_r8g8b8a8_premultiplied;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8A8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
|
||||
func = r8g8b8a8_to_b8g8r8a8_premultiplied;
|
||||
else if (src_format == GDK_MEMORY_R8G8B8A8 && dest_format == GDK_MEMORY_B8G8R8A8_PREMULTIPLIED)
|
||||
func = r8g8b8a8_to_b8g8r8a8_premultiplied;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8A8 && dest_format == GDK_MEMORY_B8G8R8A8_PREMULTIPLIED)
|
||||
func = r8g8b8a8_to_r8g8b8a8_premultiplied;
|
||||
else if (src_format == GDK_MEMORY_R8G8B8A8 && dest_format == GDK_MEMORY_A8R8G8B8_PREMULTIPLIED)
|
||||
func = r8g8b8a8_to_a8r8g8b8_premultiplied;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8A8 && dest_format == GDK_MEMORY_A8R8G8B8_PREMULTIPLIED)
|
||||
func = r8g8b8a8_to_a8b8g8r8_premultiplied;
|
||||
else if (src_format == GDK_MEMORY_R8G8B8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
|
||||
func = r8g8b8_to_r8g8b8a8;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
|
||||
func = r8g8b8_to_b8g8r8a8;
|
||||
else if (src_format == GDK_MEMORY_R8G8B8 && dest_format == GDK_MEMORY_B8G8R8A8_PREMULTIPLIED)
|
||||
func = r8g8b8_to_b8g8r8a8;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8 && dest_format == GDK_MEMORY_B8G8R8A8_PREMULTIPLIED)
|
||||
func = r8g8b8_to_r8g8b8a8;
|
||||
else if (src_format == GDK_MEMORY_R8G8B8 && dest_format == GDK_MEMORY_A8R8G8B8_PREMULTIPLIED)
|
||||
func = r8g8b8_to_a8r8g8b8;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8 && dest_format == GDK_MEMORY_A8R8G8B8_PREMULTIPLIED)
|
||||
func = r8g8b8_to_a8b8g8r8;
|
||||
else if (src_format == GDK_MEMORY_R8G8B8 && dest_format == GDK_MEMORY_R8G8B8A8)
|
||||
func = r8g8b8_to_r8g8b8a8;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8 && dest_format == GDK_MEMORY_R8G8B8A8)
|
||||
func = r8g8b8_to_b8g8r8a8;
|
||||
else if (src_format == GDK_MEMORY_R8G8B8 && dest_format == GDK_MEMORY_B8G8R8A8)
|
||||
func = r8g8b8_to_b8g8r8a8;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8 && dest_format == GDK_MEMORY_B8G8R8A8)
|
||||
func = r8g8b8_to_r8g8b8a8;
|
||||
else if (src_format == GDK_MEMORY_R8G8B8 && dest_format == GDK_MEMORY_A8R8G8B8)
|
||||
func = r8g8b8_to_a8r8g8b8;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8 && dest_format == GDK_MEMORY_A8R8G8B8)
|
||||
func = r8g8b8_to_a8b8g8r8;
|
||||
|
||||
if (func != NULL)
|
||||
stride = desc->bytes_per_pixel * width;
|
||||
if (stride == src_stride && stride == dest_stride)
|
||||
{
|
||||
memcpy (dest_data, src_data, stride * height);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
func (dest_data, src_data, width);
|
||||
memcpy (dest_data + y * dest_stride,
|
||||
src_data + y * src_stride,
|
||||
stride);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_memory_convert_no_transform (guchar *dest_data,
|
||||
gsize dest_stride,
|
||||
GdkMemoryFormat dest_format,
|
||||
const guchar *src_data,
|
||||
gsize src_stride,
|
||||
GdkMemoryFormat src_format,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
if (dest_format == src_format)
|
||||
{
|
||||
gdk_memory_convert_same_format (dest_data, dest_stride,
|
||||
src_data, src_stride,
|
||||
width, height,
|
||||
dest_format);
|
||||
}
|
||||
else
|
||||
{
|
||||
const GdkMemoryFormatDescription *dest_desc = &memory_formats[dest_format];
|
||||
const GdkMemoryFormatDescription *src_desc = &memory_formats[src_format];
|
||||
float *tmp;
|
||||
gsize y;
|
||||
|
||||
tmp = g_new (float, width * 4);
|
||||
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
src_desc->to_float (tmp, src_data, width);
|
||||
if (src_desc->alpha == GDK_MEMORY_ALPHA_PREMULTIPLIED && dest_desc->alpha == GDK_MEMORY_ALPHA_STRAIGHT)
|
||||
unpremultiply (tmp, width);
|
||||
else if (src_desc->alpha == GDK_MEMORY_ALPHA_STRAIGHT && dest_desc->alpha != GDK_MEMORY_ALPHA_STRAIGHT)
|
||||
premultiply (tmp, width);
|
||||
dest_desc->from_float (dest_data, tmp, width);
|
||||
src_data += src_stride;
|
||||
dest_data += dest_stride;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
tmp = g_new (float, width * 4);
|
||||
g_free (tmp);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_memory_convert_transform (guchar *dest_data,
|
||||
gsize dest_stride,
|
||||
GdkMemoryFormat dest_format,
|
||||
GdkColorSpace *dest_color_space,
|
||||
const guchar *src_data,
|
||||
gsize src_stride,
|
||||
GdkMemoryFormat src_format,
|
||||
GdkColorSpace *src_color_space,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
const GdkMemoryFormatDescription *dest_desc = &memory_formats[dest_format];
|
||||
const GdkMemoryFormatDescription *src_desc = &memory_formats[src_format];
|
||||
cmsHTRANSFORM transform;
|
||||
guchar *src_tmp, *dest_tmp;
|
||||
gsize y;
|
||||
|
||||
transform = gdk_color_space_lookup_transform (src_color_space,
|
||||
src_desc->lcms.type,
|
||||
dest_color_space,
|
||||
dest_desc->lcms.type);
|
||||
|
||||
if (src_desc->to_lcms)
|
||||
src_tmp = g_malloc_n (src_desc->lcms.bpp, width);
|
||||
else
|
||||
src_tmp = NULL;
|
||||
if (dest_desc->from_lcms)
|
||||
dest_tmp = g_malloc_n (dest_desc->lcms.bpp, width);
|
||||
else
|
||||
dest_tmp = NULL;
|
||||
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
src_desc->to_float (tmp, src_data, width);
|
||||
if (src_desc->alpha == GDK_MEMORY_ALPHA_PREMULTIPLIED && dest_desc->alpha == GDK_MEMORY_ALPHA_STRAIGHT)
|
||||
unpremultiply (tmp, width);
|
||||
else if (src_desc->alpha == GDK_MEMORY_ALPHA_STRAIGHT && dest_desc->alpha != GDK_MEMORY_ALPHA_STRAIGHT)
|
||||
premultiply (tmp, width);
|
||||
dest_desc->from_float (dest_data, tmp, width);
|
||||
if (src_desc->to_lcms)
|
||||
src_desc->to_lcms (src_tmp, src_data, width);
|
||||
|
||||
cmsDoTransform (transform,
|
||||
src_tmp ? src_tmp : src_data,
|
||||
dest_tmp ? dest_tmp : dest_data,
|
||||
width);
|
||||
|
||||
if (dest_desc->from_lcms)
|
||||
dest_desc->from_lcms (dest_data, dest_tmp, width);
|
||||
|
||||
src_data += src_stride;
|
||||
dest_data += dest_stride;
|
||||
}
|
||||
|
||||
g_free (tmp);
|
||||
g_free (src_tmp);
|
||||
g_free (dest_tmp);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_memory_convert (guchar *dest_data,
|
||||
gsize dest_stride,
|
||||
GdkMemoryFormat dest_format,
|
||||
GdkColorSpace *dest_color_space,
|
||||
const guchar *src_data,
|
||||
gsize src_stride,
|
||||
GdkMemoryFormat src_format,
|
||||
GdkColorSpace *src_color_space,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
|
||||
gboolean need_transform;
|
||||
|
||||
g_assert (dest_format < GDK_MEMORY_N_FORMATS);
|
||||
g_assert (src_format < GDK_MEMORY_N_FORMATS);
|
||||
|
||||
need_transform = !gdk_color_space_equal (src_color_space, dest_color_space);
|
||||
if (!need_transform)
|
||||
{
|
||||
gdk_memory_convert_no_transform (dest_data, dest_stride, dest_format,
|
||||
src_data, src_stride, src_format,
|
||||
width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
gdk_memory_convert_transform (dest_data, dest_stride, dest_format, dest_color_space,
|
||||
src_data, src_stride, src_format, src_color_space,
|
||||
width, height);
|
||||
}
|
||||
|
||||
gdk_profiler_end_markf (start_time, "memory convert", "%zu pixels %s => %s%s",
|
||||
width * height,
|
||||
memory_formats[src_format].name,
|
||||
memory_formats[dest_format].name,
|
||||
need_transform ? " transformed" : "");
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#define __GDK_MEMORY_CONVERT_PRIVATE_H__
|
||||
|
||||
#include "gdkenums.h"
|
||||
#include "gdkcolorspace.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -43,9 +44,11 @@ gboolean gdk_memory_format_gl_format (GdkMemoryFormat
|
||||
void gdk_memory_convert (guchar *dest_data,
|
||||
gsize dest_stride,
|
||||
GdkMemoryFormat dest_format,
|
||||
GdkColorSpace *dest_color_space,
|
||||
const guchar *src_data,
|
||||
gsize src_stride,
|
||||
GdkMemoryFormat src_format,
|
||||
GdkColorSpace *src_color_space,
|
||||
gsize width,
|
||||
gsize height);
|
||||
|
||||
|
@@ -21,7 +21,9 @@
|
||||
|
||||
#include "gdkmemorytextureprivate.h"
|
||||
|
||||
#include "gdkcolorspaceprivate.h"
|
||||
#include "gdkmemoryformatprivate.h"
|
||||
#include "gdkcolorspaceprivate.h"
|
||||
#include "gsk/gl/fp16private.h"
|
||||
|
||||
/**
|
||||
@@ -58,6 +60,7 @@ gdk_memory_texture_dispose (GObject *object)
|
||||
static void
|
||||
gdk_memory_texture_download (GdkTexture *texture,
|
||||
GdkMemoryFormat format,
|
||||
GdkColorSpace *color_space,
|
||||
guchar *data,
|
||||
gsize stride)
|
||||
{
|
||||
@@ -65,9 +68,11 @@ gdk_memory_texture_download (GdkTexture *texture,
|
||||
|
||||
gdk_memory_convert (data, stride,
|
||||
format,
|
||||
color_space,
|
||||
(guchar *) g_bytes_get_data (self->bytes, NULL),
|
||||
self->stride,
|
||||
texture->format,
|
||||
gdk_texture_get_color_space (texture),
|
||||
gdk_texture_get_width (texture),
|
||||
gdk_texture_get_height (texture));
|
||||
}
|
||||
@@ -136,6 +141,9 @@ gdk_memory_sanitize (GBytes *bytes,
|
||||
* The `GBytes` must contain @stride × @height pixels
|
||||
* in the given format.
|
||||
*
|
||||
* This function calls [ctor@Gdk.MemoryTexture.new_with_color_space]
|
||||
* with the sRGB color space.
|
||||
*
|
||||
* Returns: (type GdkMemoryTexture): A newly-created `GdkTexture`
|
||||
*/
|
||||
GdkTexture *
|
||||
@@ -145,18 +153,58 @@ gdk_memory_texture_new (int width,
|
||||
GBytes *bytes,
|
||||
gsize stride)
|
||||
{
|
||||
GdkMemoryTexture *self;
|
||||
|
||||
g_return_val_if_fail (width > 0, NULL);
|
||||
g_return_val_if_fail (height > 0, NULL);
|
||||
g_return_val_if_fail (bytes != NULL, NULL);
|
||||
g_return_val_if_fail (stride >= width * gdk_memory_format_bytes_per_pixel (format), NULL);
|
||||
|
||||
return gdk_memory_texture_new_with_color_space (width, height,
|
||||
format,
|
||||
gdk_color_space_get_srgb (),
|
||||
bytes, stride);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_memory_texture_new_with_color_space:
|
||||
* @width: the width of the texture
|
||||
* @height: the height of the texture
|
||||
* @format: the format of the data
|
||||
* @color_space: a `GdkColorSpace`
|
||||
* @bytes: the `GBytes` containing the pixel data
|
||||
* @stride: rowstride for the data
|
||||
*
|
||||
* Creates a new texture for a blob of image data with a given color space.
|
||||
*
|
||||
* The `GBytes` must contain @stride x @height pixels
|
||||
* in the given format.
|
||||
*
|
||||
* Returns: A newly-created `GdkTexture`
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
GdkTexture *
|
||||
gdk_memory_texture_new_with_color_space (int width,
|
||||
int height,
|
||||
GdkMemoryFormat format,
|
||||
GdkColorSpace *color_space,
|
||||
GBytes *bytes,
|
||||
gsize stride)
|
||||
{
|
||||
GdkMemoryTexture *self;
|
||||
|
||||
g_return_val_if_fail (width > 0, NULL);
|
||||
g_return_val_if_fail (height > 0, NULL);
|
||||
g_return_val_if_fail (GDK_IS_COLOR_SPACE (color_space), NULL);
|
||||
g_return_val_if_fail (bytes != NULL, NULL);
|
||||
g_return_val_if_fail (stride >= width * gdk_memory_format_bytes_per_pixel (format), NULL);
|
||||
g_return_val_if_fail (gdk_color_space_supports_format (color_space, format), NULL);
|
||||
|
||||
bytes = gdk_memory_sanitize (bytes, width, height, format, stride, &stride);
|
||||
|
||||
self = g_object_new (GDK_TYPE_MEMORY_TEXTURE,
|
||||
"width", width,
|
||||
"height", height,
|
||||
"color-space", color_space,
|
||||
NULL);
|
||||
|
||||
GDK_TEXTURE (self)->format = format;
|
||||
@@ -201,7 +249,8 @@ gdk_memory_texture_new_subtexture (GdkMemoryTexture *source,
|
||||
|
||||
GdkMemoryTexture *
|
||||
gdk_memory_texture_from_texture (GdkTexture *texture,
|
||||
GdkMemoryFormat format)
|
||||
GdkMemoryFormat format,
|
||||
GdkColorSpace *color_space)
|
||||
{
|
||||
GdkTexture *result;
|
||||
GBytes *bytes;
|
||||
@@ -214,20 +263,22 @@ gdk_memory_texture_from_texture (GdkTexture *texture,
|
||||
{
|
||||
GdkMemoryTexture *memtex = GDK_MEMORY_TEXTURE (texture);
|
||||
|
||||
if (gdk_texture_get_format (texture) == format)
|
||||
if (gdk_texture_get_format (texture) == format &&
|
||||
gdk_texture_get_color_space (texture) == color_space)
|
||||
return g_object_ref (memtex);
|
||||
}
|
||||
|
||||
stride = texture->width * gdk_memory_format_bytes_per_pixel (format);
|
||||
data = g_malloc_n (stride, texture->height);
|
||||
|
||||
gdk_texture_do_download (texture, format, data, stride);
|
||||
gdk_texture_do_download (texture, format, color_space, data, stride);
|
||||
bytes = g_bytes_new_take (data, stride);
|
||||
result = gdk_memory_texture_new (texture->width,
|
||||
texture->height,
|
||||
format,
|
||||
bytes,
|
||||
stride);
|
||||
result = gdk_memory_texture_new_with_color_space (texture->width,
|
||||
texture->height,
|
||||
format,
|
||||
color_space,
|
||||
bytes,
|
||||
stride);
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
return GDK_MEMORY_TEXTURE (result);
|
||||
|
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <gdk/gdkenums.h>
|
||||
#include <gdk/gdktexture.h>
|
||||
#include <gdk/gdkcolorspace.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -68,6 +69,14 @@ GdkTexture * gdk_memory_texture_new (int
|
||||
GdkMemoryFormat format,
|
||||
GBytes *bytes,
|
||||
gsize stride);
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GdkTexture * gdk_memory_texture_new_with_color_space
|
||||
(int width,
|
||||
int height,
|
||||
GdkMemoryFormat format,
|
||||
GdkColorSpace *color_space,
|
||||
GBytes *bytes,
|
||||
gsize stride);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -30,7 +30,8 @@ G_BEGIN_DECLS
|
||||
#define GDK_MEMORY_GDK_PIXBUF_ALPHA GDK_MEMORY_R8G8B8A8
|
||||
|
||||
GdkMemoryTexture * gdk_memory_texture_from_texture (GdkTexture *texture,
|
||||
GdkMemoryFormat format);
|
||||
GdkMemoryFormat format,
|
||||
GdkColorSpace *color_space);
|
||||
GdkTexture * gdk_memory_texture_new_subtexture (GdkMemoryTexture *texture,
|
||||
int x,
|
||||
int y,
|
||||
|
@@ -245,7 +245,8 @@ gdk_pixbuf_get_from_texture (GdkTexture *texture)
|
||||
|
||||
memtex = gdk_memory_texture_from_texture (texture,
|
||||
alpha ? GDK_MEMORY_GDK_PIXBUF_ALPHA
|
||||
: GDK_MEMORY_GDK_PIXBUF_OPAQUE);
|
||||
: GDK_MEMORY_GDK_PIXBUF_OPAQUE,
|
||||
gdk_color_space_get_srgb ());
|
||||
|
||||
return gdk_pixbuf_new_from_data (gdk_memory_texture_get_data (memtex),
|
||||
GDK_COLORSPACE_RGB,
|
||||
|
@@ -30,6 +30,8 @@
|
||||
#include "gdksurface.h"
|
||||
|
||||
#include "gdkprivate.h"
|
||||
#include "gdkcolorspace.h"
|
||||
#include "gdkcairo.h"
|
||||
#include "gdkcontentprovider.h"
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkdisplayprivate.h"
|
||||
@@ -88,13 +90,14 @@ enum {
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_COLOR_SPACE,
|
||||
PROP_CURSOR,
|
||||
PROP_DISPLAY,
|
||||
PROP_FRAME_CLOCK,
|
||||
PROP_MAPPED,
|
||||
PROP_WIDTH,
|
||||
PROP_HEIGHT,
|
||||
PROP_MAPPED,
|
||||
PROP_SCALE_FACTOR,
|
||||
PROP_WIDTH,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
@@ -485,6 +488,8 @@ gdk_surface_init (GdkSurface *surface)
|
||||
|
||||
surface->alpha = 255;
|
||||
|
||||
surface->color_space = g_object_ref (gdk_color_space_get_srgb ());
|
||||
|
||||
surface->device_cursor = g_hash_table_new_full (NULL, NULL,
|
||||
NULL, g_object_unref);
|
||||
}
|
||||
@@ -500,6 +505,25 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
|
||||
|
||||
klass->beep = gdk_surface_real_beep;
|
||||
|
||||
/**
|
||||
* GdkSurface:color-space: (attributes org.gtk.Property.get=gdk_surface_get_color_space)
|
||||
*
|
||||
* The preferred color space for rendering to the surface
|
||||
*
|
||||
* This color space is negotiated between GTK and the compositor.
|
||||
*
|
||||
* The color space may change as the surface gets moved around - for example
|
||||
* to different monitors or when the compositor gets reconfigured. As long as
|
||||
* the surface isn't shown, the color space may not represent the actual color
|
||||
* space that is going to be used.
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
properties[PROP_COLOR_SPACE] =
|
||||
g_param_spec_object ("color-space", NULL, NULL,
|
||||
GDK_TYPE_COLOR_SPACE,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkSurface:cursor: (attributes org.gtk.Property.get=gdk_surface_get_cursor org.gtk.Property.set=gdk_surface_set_cursor)
|
||||
*
|
||||
@@ -718,6 +742,7 @@ gdk_surface_finalize (GObject *object)
|
||||
g_clear_object (&surface->cursor);
|
||||
g_clear_pointer (&surface->device_cursor, g_hash_table_destroy);
|
||||
g_clear_pointer (&surface->devices_inside, g_list_free);
|
||||
g_clear_object (&surface->color_space);
|
||||
|
||||
g_clear_object (&surface->display);
|
||||
|
||||
@@ -772,6 +797,10 @@ gdk_surface_get_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_COLOR_SPACE:
|
||||
g_value_set_object (value, gdk_surface_get_color_space (surface));
|
||||
break;
|
||||
|
||||
case PROP_CURSOR:
|
||||
g_value_set_object (value, gdk_surface_get_cursor (surface));
|
||||
break;
|
||||
@@ -2040,6 +2069,40 @@ gdk_surface_get_height (GdkSurface *surface)
|
||||
return surface->height;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_surface_set_color_space (GdkSurface *self,
|
||||
GdkColorSpace *color_space)
|
||||
{
|
||||
/* This way we support unsetting, too */
|
||||
if (G_UNLIKELY (gdk_display_get_debug_flags (self->display) & GDK_DEBUG_SRGB))
|
||||
color_space = gdk_color_space_get_srgb ();
|
||||
|
||||
if (gdk_color_space_equal (self->color_space, color_space))
|
||||
return;
|
||||
|
||||
g_set_object (&self->color_space, color_space);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_COLOR_SPACE]);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_surface_get_color_space: (attributes org.gtk.Method.get_property=color-space)
|
||||
* @self: a `GdkSurface`
|
||||
*
|
||||
* Returns the preferred color space for rendering to the given @surface.
|
||||
*
|
||||
* Returns: (transfer none): The color space of @surface
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
GdkColorSpace *
|
||||
gdk_surface_get_color_space (GdkSurface *self)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_SURFACE (self), gdk_color_space_get_srgb ());
|
||||
|
||||
return self->color_space;
|
||||
}
|
||||
|
||||
/*
|
||||
* gdk_surface_get_origin:
|
||||
* @surface: a `GdkSurface`
|
||||
@@ -2360,7 +2423,7 @@ _gdk_windowing_got_event (GdkDisplay *display,
|
||||
* with it.
|
||||
*/
|
||||
cairo_surface_t *
|
||||
gdk_surface_create_similar_surface (GdkSurface * surface,
|
||||
gdk_surface_create_similar_surface (GdkSurface * surface,
|
||||
cairo_content_t content,
|
||||
int width,
|
||||
int height)
|
||||
@@ -2376,6 +2439,7 @@ gdk_surface_create_similar_surface (GdkSurface * surface,
|
||||
content == CAIRO_CONTENT_ALPHA ? CAIRO_FORMAT_A8 : CAIRO_FORMAT_ARGB32,
|
||||
width * scale, height * scale);
|
||||
cairo_surface_set_device_scale (similar_surface, scale, scale);
|
||||
gdk_cairo_surface_set_color_space (similar_surface, gdk_surface_get_color_space (surface));
|
||||
|
||||
return similar_surface;
|
||||
}
|
||||
|
@@ -86,17 +86,19 @@ GDK_AVAILABLE_IN_ALL
|
||||
GdkCursor *gdk_surface_get_device_cursor (GdkSurface *surface,
|
||||
GdkDevice *device);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
int gdk_surface_get_width (GdkSurface *surface);
|
||||
int gdk_surface_get_width (GdkSurface *surface);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
int gdk_surface_get_height (GdkSurface *surface);
|
||||
int gdk_surface_get_height (GdkSurface *surface);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_surface_translate_coordinates (GdkSurface *from,
|
||||
GdkSurface *to,
|
||||
double *x,
|
||||
double *y);
|
||||
int gdk_surface_get_scale_factor (GdkSurface *surface);
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GdkColorSpace * gdk_surface_get_color_space (GdkSurface *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_surface_translate_coordinates (GdkSurface *from,
|
||||
GdkSurface *to,
|
||||
double *x,
|
||||
double *y);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
int gdk_surface_get_scale_factor (GdkSurface *surface);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_surface_get_device_position (GdkSurface *surface,
|
||||
|
@@ -52,6 +52,7 @@ struct _GdkSurface
|
||||
int y;
|
||||
|
||||
GdkGLContext *gl_paint_context;
|
||||
GdkColorSpace *color_space;
|
||||
|
||||
cairo_region_t *update_area;
|
||||
guint update_freeze_count;
|
||||
@@ -171,6 +172,8 @@ void gdk_surface_set_state (GdkSurface *surface,
|
||||
|
||||
void gdk_surface_set_is_mapped (GdkSurface *surface,
|
||||
gboolean is_mapped);
|
||||
void gdk_surface_set_color_space (GdkSurface *self,
|
||||
GdkColorSpace *color_space);
|
||||
|
||||
GdkMonitor * gdk_surface_get_layout_monitor (GdkSurface *surface,
|
||||
GdkPopupLayout *layout,
|
||||
|
155
gdk/gdktexture.c
@@ -40,6 +40,9 @@
|
||||
#include "gdktextureprivate.h"
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include "gdkcolorspace.h"
|
||||
#include "gdkcairo.h"
|
||||
#include "gdkmemoryformatprivate.h"
|
||||
#include "gdkmemorytextureprivate.h"
|
||||
#include "gdkpaintable.h"
|
||||
#include "gdksnapshot.h"
|
||||
@@ -61,6 +64,7 @@ enum {
|
||||
PROP_0,
|
||||
PROP_WIDTH,
|
||||
PROP_HEIGHT,
|
||||
PROP_COLOR_SPACE,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
@@ -223,6 +227,7 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GdkTexture, gdk_texture, G_TYPE_OBJECT,
|
||||
static void
|
||||
gdk_texture_default_download (GdkTexture *texture,
|
||||
GdkMemoryFormat format,
|
||||
GdkColorSpace *color_space,
|
||||
guchar *data,
|
||||
gsize stride)
|
||||
{
|
||||
@@ -247,6 +252,12 @@ gdk_texture_set_property (GObject *gobject,
|
||||
self->height = g_value_get_int (value);
|
||||
break;
|
||||
|
||||
case PROP_COLOR_SPACE:
|
||||
self->color_space = g_value_dup_object (value);
|
||||
if (self->color_space == NULL)
|
||||
self->color_space = g_object_ref (gdk_color_space_get_srgb ());
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
@@ -271,6 +282,10 @@ gdk_texture_get_property (GObject *gobject,
|
||||
g_value_set_int (value, self->height);
|
||||
break;
|
||||
|
||||
case PROP_COLOR_SPACE:
|
||||
g_value_set_object (value, self->color_space);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
@@ -283,6 +298,7 @@ gdk_texture_dispose (GObject *object)
|
||||
GdkTexture *self = GDK_TEXTURE (object);
|
||||
|
||||
gdk_texture_clear_render_data (self);
|
||||
g_clear_object (&self->color_space);
|
||||
|
||||
G_OBJECT_CLASS (gdk_texture_parent_class)->dispose (object);
|
||||
}
|
||||
@@ -305,9 +321,7 @@ gdk_texture_class_init (GdkTextureClass *klass)
|
||||
*/
|
||||
properties[PROP_WIDTH] =
|
||||
g_param_spec_int ("width", NULL, NULL,
|
||||
1,
|
||||
G_MAXINT,
|
||||
1,
|
||||
1, G_MAXINT, 1,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
@@ -320,14 +334,27 @@ gdk_texture_class_init (GdkTextureClass *klass)
|
||||
*/
|
||||
properties[PROP_HEIGHT] =
|
||||
g_param_spec_int ("height", NULL, NULL,
|
||||
1,
|
||||
G_MAXINT,
|
||||
1,
|
||||
1, G_MAXINT, 1,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkTexture:color-space: (attributes org.gtk.Property.get=gdk_texture_get_color_space)
|
||||
*
|
||||
* The color space associated with texture.
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
properties[PROP_COLOR_SPACE] =
|
||||
g_param_spec_object ("color-space", NULL, NULL,
|
||||
GDK_TYPE_COLOR_SPACE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
g_object_class_install_properties (gobject_class, N_PROPS, properties);
|
||||
}
|
||||
|
||||
@@ -361,18 +388,43 @@ gdk_texture_new_for_surface (cairo_surface_t *surface)
|
||||
* cairo_image_surface_get_stride (surface),
|
||||
(GDestroyNotify) cairo_surface_destroy,
|
||||
cairo_surface_reference (surface));
|
||||
|
||||
texture = gdk_memory_texture_new (cairo_image_surface_get_width (surface),
|
||||
cairo_image_surface_get_height (surface),
|
||||
GDK_MEMORY_DEFAULT,
|
||||
bytes,
|
||||
cairo_image_surface_get_stride (surface));
|
||||
|
||||
texture = gdk_memory_texture_new_with_color_space (cairo_image_surface_get_width (surface),
|
||||
cairo_image_surface_get_height (surface),
|
||||
GDK_MEMORY_DEFAULT,
|
||||
gdk_cairo_surface_get_color_space (surface),
|
||||
bytes,
|
||||
cairo_image_surface_get_stride (surface));
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
static GdkColorSpace *
|
||||
gdk_color_space_from_pixbuf (GdkPixbuf *pixbuf)
|
||||
{
|
||||
const char *icc_profile_base64;
|
||||
GdkColorSpace *color_space = NULL;
|
||||
|
||||
icc_profile_base64 = gdk_pixbuf_get_option (pixbuf, "icc-profile");
|
||||
if (icc_profile_base64)
|
||||
{
|
||||
guchar *icc_data;
|
||||
gsize icc_len;
|
||||
GBytes *bytes;
|
||||
|
||||
icc_data = g_base64_decode (icc_profile_base64, &icc_len);
|
||||
bytes = g_bytes_new_take (icc_data, icc_len);
|
||||
color_space = gdk_color_space_new_from_icc_profile (bytes, NULL);
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
if (!color_space)
|
||||
color_space = g_object_ref (gdk_color_space_get_srgb ());
|
||||
|
||||
return color_space;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_texture_new_for_pixbuf:
|
||||
* @pixbuf: a `GdkPixbuf`
|
||||
@@ -390,24 +442,31 @@ gdk_texture_new_for_pixbuf (GdkPixbuf *pixbuf)
|
||||
{
|
||||
GdkTexture *texture;
|
||||
GBytes *bytes;
|
||||
GdkColorSpace *color_space;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
|
||||
|
||||
color_space = gdk_color_space_from_pixbuf (pixbuf);
|
||||
|
||||
bytes = g_bytes_new_with_free_func (gdk_pixbuf_get_pixels (pixbuf),
|
||||
gdk_pixbuf_get_height (pixbuf)
|
||||
* gdk_pixbuf_get_rowstride (pixbuf),
|
||||
g_object_unref,
|
||||
g_object_ref (pixbuf));
|
||||
texture = gdk_memory_texture_new (gdk_pixbuf_get_width (pixbuf),
|
||||
gdk_pixbuf_get_height (pixbuf),
|
||||
gdk_pixbuf_get_has_alpha (pixbuf)
|
||||
? GDK_MEMORY_GDK_PIXBUF_ALPHA
|
||||
: GDK_MEMORY_GDK_PIXBUF_OPAQUE,
|
||||
bytes,
|
||||
gdk_pixbuf_get_rowstride (pixbuf));
|
||||
|
||||
texture = gdk_memory_texture_new_with_color_space (gdk_pixbuf_get_width (pixbuf),
|
||||
gdk_pixbuf_get_height (pixbuf),
|
||||
gdk_pixbuf_get_has_alpha (pixbuf)
|
||||
? GDK_MEMORY_GDK_PIXBUF_ALPHA
|
||||
: GDK_MEMORY_GDK_PIXBUF_OPAQUE,
|
||||
color_space,
|
||||
bytes,
|
||||
gdk_pixbuf_get_rowstride (pixbuf));
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
g_object_unref (color_space);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
@@ -665,32 +724,73 @@ gdk_texture_get_height (GdkTexture *texture)
|
||||
return texture->height;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_texture_get_color_space: (attributes org.gtk.Method.get_property=color-space)
|
||||
* @texture: a `GdkTexture`
|
||||
*
|
||||
* Returns the color space associsated with @texture.
|
||||
*
|
||||
* Returns: (transfer none): the color space of the `GdkTexture`
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
GdkColorSpace *
|
||||
gdk_texture_get_color_space (GdkTexture *texture)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_TEXTURE (texture), 0);
|
||||
|
||||
return texture->color_space;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_texture_do_download (GdkTexture *texture,
|
||||
GdkMemoryFormat format,
|
||||
GdkColorSpace *color_space,
|
||||
guchar *data,
|
||||
gsize stride)
|
||||
{
|
||||
GDK_TEXTURE_GET_CLASS (texture)->download (texture, format, data,stride);
|
||||
GDK_TEXTURE_GET_CLASS (texture)->download (texture, format, color_space, data, stride);
|
||||
}
|
||||
|
||||
/*<private>
|
||||
* gdk_texture_download_surface:
|
||||
* @texture: the texture to download
|
||||
* @color_space: (nullable): The target color space or %NULL for the default sRGB
|
||||
*
|
||||
* Downloads the texture into a newly created Cairo surface.
|
||||
*
|
||||
* Returns: A new Cairo surface.
|
||||
**/
|
||||
cairo_surface_t *
|
||||
gdk_texture_download_surface (GdkTexture *texture)
|
||||
gdk_texture_download_surface (GdkTexture *texture,
|
||||
GdkColorSpace *color_space)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
cairo_status_t surface_status;
|
||||
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
texture->width, texture->height);
|
||||
if (color_space != NULL)
|
||||
gdk_cairo_surface_set_color_space (surface, color_space);
|
||||
else
|
||||
color_space = gdk_color_space_get_srgb ();
|
||||
|
||||
surface_status = cairo_surface_status (surface);
|
||||
if (surface_status != CAIRO_STATUS_SUCCESS)
|
||||
g_warning ("%s: surface error: %s", __FUNCTION__,
|
||||
cairo_status_to_string (surface_status));
|
||||
{
|
||||
g_warning ("%s: surface error: %s", __FUNCTION__,
|
||||
cairo_status_to_string (surface_status));
|
||||
}
|
||||
else
|
||||
{
|
||||
gdk_texture_do_download (texture,
|
||||
GDK_MEMORY_DEFAULT,
|
||||
color_space,
|
||||
cairo_image_surface_get_data (surface),
|
||||
cairo_image_surface_get_stride (surface));
|
||||
}
|
||||
|
||||
gdk_texture_download (texture,
|
||||
cairo_image_surface_get_data (surface),
|
||||
cairo_image_surface_get_stride (surface));
|
||||
cairo_surface_mark_dirty (surface);
|
||||
|
||||
return surface;
|
||||
@@ -734,6 +834,7 @@ gdk_texture_download (GdkTexture *texture,
|
||||
|
||||
gdk_texture_do_download (texture,
|
||||
GDK_MEMORY_DEFAULT,
|
||||
gdk_color_space_get_srgb (),
|
||||
data,
|
||||
stride);
|
||||
}
|
||||
@@ -751,7 +852,7 @@ gdk_texture_set_render_data (GdkTexture *self,
|
||||
GDestroyNotify notify)
|
||||
{
|
||||
g_return_val_if_fail (data != NULL, FALSE);
|
||||
|
||||
|
||||
if (self->render_key != NULL)
|
||||
return FALSE;
|
||||
|
||||
|
@@ -82,6 +82,8 @@ GDK_AVAILABLE_IN_ALL
|
||||
int gdk_texture_get_width (GdkTexture *texture) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
int gdk_texture_get_height (GdkTexture *texture) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GdkColorSpace * gdk_texture_get_color_space (GdkTexture *texture) G_GNUC_PURE;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_texture_download (GdkTexture *texture,
|
||||
|