Bug Summary

File:ctk/deprecated/ctkgradient.c
Warning:line 513, column 12
This statement is never executed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ctkgradient.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/rootdir/ctk -fcoverage-compilation-dir=/rootdir/ctk -resource-dir /usr/lib/llvm-21/lib/clang/21 -D HAVE_CONFIG_H -I . -I .. -D G_LOG_DOMAIN="Ctk" -D G_LOG_USE_STRUCTURED=1 -D CTK_VERSION="3.25.7" -D CTK_BINARY_VERSION="3.0.0" -D CTK_COMPILATION -D CTK_PRINT_BACKEND_ENABLE_UNSUPPORTED -D CTK_LIBDIR="/usr/lib" -D CTK_LOCALEDIR="/usr/share/locale" -D CTK_DATADIR="/usr/share" -D CTK_DATA_PREFIX="/usr" -D CTK_SYSCONFDIR="/usr/etc" -D CTK_HOST="x86_64-pc-linux-gnu" -D CTK_PRINT_BACKENDS="file,cups" -D X11_DATA_PREFIX="/usr" -D ISO_CODES_PREFIX="" -I .. -I ../ctk -I .. -I ../cdk -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -D G_ENABLE_DEBUG -D G_ENABLE_CONSISTENCY_CHECKS -D GLIB_MIN_REQUIRED_VERSION=GLIB_VERSION_2_66 -D GLIB_MAX_ALLOWED_VERSION=GLIB_VERSION_2_66 -I /usr/include/pango-1.0 -I /usr/include/cairo -I /usr/local/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/atk-1.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/fribidi -I /usr/include/pixman-1 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/gio-unix-2.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/sysprof-6 -I /usr/include/pango-1.0 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -D PIC -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/15/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -analyzer-checker deadcode.DeadStores -analyzer-checker security.ArrayBound -analyzer-checker unix.cstring.NotNullTerminated -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2026-05-20-090151-45479-1 -x c deprecated/ctkgradient.c
1/* CTK - The GIMP Toolkit
2 * Copyright (C) 2010 Carlos Garnacho <carlosg@gnome.org>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "config.h"
19
20#define CDK_DISABLE_DEPRECATION_WARNINGS
21
22#include "ctkgradientprivate.h"
23#include "ctkcsscolorvalueprivate.h"
24#include "ctkcssrgbavalueprivate.h"
25#include "ctkstylecontextprivate.h"
26#include "ctkstyleproperties.h"
27#include "ctksymboliccolorprivate.h"
28
29/**
30 * SECTION:ctkgradient
31 * @Short_description: Gradients
32 * @Title: CtkGradient
33 *
34 * CtkGradient is a boxed type that represents a gradient.
35 * It is the result of parsing a
36 * [gradient expression][ctkcssprovider-gradients].
37 * To obtain the gradient represented by a CtkGradient, it has to
38 * be resolved with ctk_gradient_resolve(), which replaces all
39 * symbolic color references by the colors they refer to (in a given
40 * context) and constructs a #cairo_pattern_t value.
41 *
42 * It is not normally necessary to deal directly with #CtkGradients,
43 * since they are mostly used behind the scenes by #CtkStyleContext and
44 * #CtkCssProvider.
45 *
46 * #CtkGradient is deprecated. It was used internally by CTK’s CSS engine
47 * to represent gradients. As its handling is not conforming to modern
48 * web standards, it is not used anymore. If you want to use gradients in
49 * your own code, please use Cairo directly.
50 */
51
52G_DEFINE_BOXED_TYPE (CtkGradient, ctk_gradient,static GType ctk_gradient_get_type_once (void); GType ctk_gradient_get_type
(void) { static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_gradient_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType ctk_gradient_get_type_once (void
) { GType (* _g_register_boxed) (const gchar *, union { CtkGradient
* (*do_copy_type) (CtkGradient *); CtkGradient * (*do_const_copy_type
) (const CtkGradient *); GBoxedCopyFunc do_copy_boxed; } __attribute__
((__transparent_union__)), union { void (* do_free_type) (CtkGradient
*); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__
)) ) = g_boxed_type_register_static; GType g_define_type_id =
_g_register_boxed (g_intern_static_string ("CtkGradient"), ctk_gradient_ref
, ctk_gradient_unref); { {{};} } return g_define_type_id; }
53 ctk_gradient_ref, ctk_gradient_unref)static GType ctk_gradient_get_type_once (void); GType ctk_gradient_get_type
(void) { static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_gradient_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType ctk_gradient_get_type_once (void
) { GType (* _g_register_boxed) (const gchar *, union { CtkGradient
* (*do_copy_type) (CtkGradient *); CtkGradient * (*do_const_copy_type
) (const CtkGradient *); GBoxedCopyFunc do_copy_boxed; } __attribute__
((__transparent_union__)), union { void (* do_free_type) (CtkGradient
*); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__
)) ) = g_boxed_type_register_static; GType g_define_type_id =
_g_register_boxed (g_intern_static_string ("CtkGradient"), ctk_gradient_ref
, ctk_gradient_unref); { {{};} } return g_define_type_id; }
54
55typedef struct ColorStop ColorStop;
56
57struct ColorStop
58{
59 gdouble offset;
60 CtkSymbolicColor *color;
61};
62
63struct _CtkGradient
64{
65 gdouble x0;
66 gdouble y0;
67 gdouble x1;
68 gdouble y1;
69 gdouble radius0;
70 gdouble radius1;
71
72 GArray *stops;
73
74 guint ref_count;
75};
76
77/**
78 * ctk_gradient_new_linear:
79 * @x0: X coordinate of the starting point
80 * @y0: Y coordinate of the starting point
81 * @x1: X coordinate of the end point
82 * @y1: Y coordinate of the end point
83 *
84 * Creates a new linear gradient along the line defined by (x0, y0) and (x1, y1). Before using the gradient
85 * a number of stop colors must be added through ctk_gradient_add_color_stop().
86 *
87 * Returns: A newly created #CtkGradient
88 *
89 * Since: 3.0
90 *
91 * Deprecated: 3.8: #CtkGradient is deprecated.
92 **/
93CtkGradient *
94ctk_gradient_new_linear (gdouble x0,
95 gdouble y0,
96 gdouble x1,
97 gdouble y1)
98{
99 CtkGradient *gradient;
100
101 gradient = g_slice_new (CtkGradient)((CtkGradient*) g_slice_alloc ((sizeof (CtkGradient) > 0 ?
sizeof (CtkGradient) : 1)))
;
102 gradient->stops = g_array_new (FALSE(0), FALSE(0), sizeof (ColorStop));
103
104 gradient->x0 = x0;
105 gradient->y0 = y0;
106 gradient->x1 = x1;
107 gradient->y1 = y1;
108 gradient->radius0 = 0;
109 gradient->radius1 = 0;
110
111 gradient->ref_count = 1;
112
113 return gradient;
114}
115
116/**
117 * ctk_gradient_new_radial:
118 * @x0: X coordinate of the start circle
119 * @y0: Y coordinate of the start circle
120 * @radius0: radius of the start circle
121 * @x1: X coordinate of the end circle
122 * @y1: Y coordinate of the end circle
123 * @radius1: radius of the end circle
124 *
125 * Creates a new radial gradient along the two circles defined by (x0, y0, radius0) and
126 * (x1, y1, radius1). Before using the gradient a number of stop colors must be added
127 * through ctk_gradient_add_color_stop().
128 *
129 * Returns: A newly created #CtkGradient
130 *
131 * Since: 3.0
132 *
133 * Deprecated: 3.8: #CtkGradient is deprecated.
134 **/
135CtkGradient *
136ctk_gradient_new_radial (gdouble x0,
137 gdouble y0,
138 gdouble radius0,
139 gdouble x1,
140 gdouble y1,
141 gdouble radius1)
142{
143 CtkGradient *gradient;
144
145 gradient = g_slice_new (CtkGradient)((CtkGradient*) g_slice_alloc ((sizeof (CtkGradient) > 0 ?
sizeof (CtkGradient) : 1)))
;
146 gradient->stops = g_array_new (FALSE(0), FALSE(0), sizeof (ColorStop));
147
148 gradient->x0 = x0;
149 gradient->y0 = y0;
150 gradient->x1 = x1;
151 gradient->y1 = y1;
152 gradient->radius0 = radius0;
153 gradient->radius1 = radius1;
154
155 gradient->ref_count = 1;
156
157 return gradient;
158}
159
160/**
161 * ctk_gradient_add_color_stop:
162 * @gradient: a #CtkGradient
163 * @offset: offset for the color stop
164 * @color: color to use
165 *
166 * Adds a stop color to @gradient.
167 *
168 * Since: 3.0
169 *
170 * Deprecated: 3.8: #CtkGradient is deprecated.
171 **/
172void
173ctk_gradient_add_color_stop (CtkGradient *gradient,
174 gdouble offset,
175 CtkSymbolicColor *color)
176{
177 ColorStop stop;
178
179 g_return_if_fail (gradient != NULL)do { if ((gradient != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "gradient != NULL"); return
; } } while (0)
;
180
181 stop.offset = offset;
182 stop.color = ctk_symbolic_color_ref (color);
183
184 g_array_append_val (gradient->stops, stop)g_array_append_vals (gradient->stops, &(stop), 1);
185}
186
187/**
188 * ctk_gradient_ref:
189 * @gradient: a #CtkGradient
190 *
191 * Increases the reference count of @gradient.
192 *
193 * Returns: The same @gradient
194 *
195 * Since: 3.0
196 *
197 * Deprecated: 3.8: #CtkGradient is deprecated.
198 **/
199CtkGradient *
200ctk_gradient_ref (CtkGradient *gradient)
201{
202 g_return_val_if_fail (gradient != NULL, NULL)do { if ((gradient != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "gradient != NULL"); return
(((void*)0)); } } while (0)
;
203
204 gradient->ref_count++;
205
206 return gradient;
207}
208
209/**
210 * ctk_gradient_unref:
211 * @gradient: a #CtkGradient
212 *
213 * Decreases the reference count of @gradient, freeing its memory
214 * if the reference count reaches 0.
215 *
216 * Since: 3.0
217 *
218 * Deprecated: 3.8: #CtkGradient is deprecated.
219 **/
220void
221ctk_gradient_unref (CtkGradient *gradient)
222{
223 g_return_if_fail (gradient != NULL)do { if ((gradient != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "gradient != NULL"); return
; } } while (0)
;
224
225 gradient->ref_count--;
226
227 if (gradient->ref_count == 0)
228 {
229 guint i;
230
231 for (i = 0; i < gradient->stops->len; i++)
232 {
233 ColorStop *stop;
234
235 stop = &g_array_index (gradient->stops, ColorStop, i)(((ColorStop*) (void *) (gradient->stops)->data) [(i)]);
236 ctk_symbolic_color_unref (stop->color);
237 }
238
239 g_array_free (gradient->stops, TRUE(!(0)));
240 g_slice_free (CtkGradient, gradient)do { if (1) g_slice_free1 (sizeof (CtkGradient), (gradient));
else (void) ((CtkGradient*) 0 == (gradient)); } while (0)
;
241 }
242}
243
244/**
245 * ctk_gradient_resolve:
246 * @gradient: a #CtkGradient
247 * @props: #CtkStyleProperties to use when resolving named colors
248 * @resolved_gradient: (out): return location for the resolved pattern
249 *
250 * If @gradient is resolvable, @resolved_gradient will be filled in
251 * with the resolved gradient as a cairo_pattern_t, and %TRUE will
252 * be returned. Generally, if @gradient can’t be resolved, it is
253 * due to it being defined on top of a named color that doesn't
254 * exist in @props.
255 *
256 * Returns: %TRUE if the gradient has been resolved
257 *
258 * Since: 3.0
259 *
260 * Deprecated: 3.8: #CtkGradient is deprecated.
261 **/
262gboolean
263ctk_gradient_resolve (CtkGradient *gradient,
264 CtkStyleProperties *props,
265 cairo_pattern_t **resolved_gradient)
266{
267 cairo_pattern_t *pattern;
268 guint i;
269
270 g_return_val_if_fail (gradient != NULL, FALSE)do { if ((gradient != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "gradient != NULL"); return
((0)); } } while (0)
;
271 g_return_val_if_fail (CTK_IS_STYLE_PROPERTIES (props), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((props)); GType __t = ((ctk_style_properties_get_type ())
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const
char*) (__func__)), "CTK_IS_STYLE_PROPERTIES (props)"); return
((0)); } } while (0)
;
272 g_return_val_if_fail (resolved_gradient != NULL, FALSE)do { if ((resolved_gradient != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "resolved_gradient != NULL"
); return ((0)); } } while (0)
;
273
274 if (gradient->radius0 == 0 && gradient->radius1 == 0)
275 pattern = cairo_pattern_create_linear (gradient->x0, gradient->y0,
276 gradient->x1, gradient->y1);
277 else
278 pattern = cairo_pattern_create_radial (gradient->x0, gradient->y0,
279 gradient->radius0,
280 gradient->x1, gradient->y1,
281 gradient->radius1);
282
283 for (i = 0; i < gradient->stops->len; i++)
284 {
285 ColorStop *stop;
286 CdkRGBA color;
287
288 stop = &g_array_index (gradient->stops, ColorStop, i)(((ColorStop*) (void *) (gradient->stops)->data) [(i)]);
289
290 if (!ctk_symbolic_color_resolve (stop->color, props, &color))
291 {
292 cairo_pattern_destroy (pattern);
293 return FALSE(0);
294 }
295
296 cairo_pattern_add_color_stop_rgba (pattern, stop->offset,
297 color.red, color.green,
298 color.blue, color.alpha);
299 }
300
301 *resolved_gradient = pattern;
302 return TRUE(!(0));
303}
304
305cairo_pattern_t *
306_ctk_gradient_resolve_full (CtkGradient *gradient,
307 CtkStyleProviderPrivate *provider,
308 CtkCssStyle *style,
309 CtkCssStyle *parent_style)
310{
311 cairo_pattern_t *pattern;
312 guint i;
313
314 g_return_val_if_fail (gradient != NULL, NULL)do { if ((gradient != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "gradient != NULL"); return
(((void*)0)); } } while (0)
;
315 g_return_val_if_fail (CTK_IS_STYLE_PROVIDER (provider), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((provider)); GType __t = ((ctk_style_provider_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const
char*) (__func__)), "CTK_IS_STYLE_PROVIDER (provider)"); return
(((void*)0)); } } while (0)
;
316 g_return_val_if_fail (CTK_IS_CSS_STYLE (style), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) (style); GType __t = ((ctk_css_style_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_CSS_STYLE (style)"); return (((void*)0)); } } while
(0)
;
317 g_return_val_if_fail (parent_style == NULL || CTK_IS_CSS_STYLE (parent_style), NULL)do { if ((parent_style == ((void*)0) || (((__extension__ ({ GTypeInstance
*__inst = (GTypeInstance*) (parent_style); GType __t = ((ctk_css_style_get_type
())); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const
char*) (__func__)), "parent_style == NULL || CTK_IS_CSS_STYLE (parent_style)"
); return (((void*)0)); } } while (0)
;
318
319 if (gradient->radius0 == 0 && gradient->radius1 == 0)
320 pattern = cairo_pattern_create_linear (gradient->x0, gradient->y0,
321 gradient->x1, gradient->y1);
322 else
323 pattern = cairo_pattern_create_radial (gradient->x0, gradient->y0,
324 gradient->radius0,
325 gradient->x1, gradient->y1,
326 gradient->radius1);
327
328 for (i = 0; i < gradient->stops->len; i++)
329 {
330 ColorStop *stop;
331 CtkCssValue *val;
332 CdkRGBA rgba;
333
334 stop = &g_array_index (gradient->stops, ColorStop, i)(((ColorStop*) (void *) (gradient->stops)->data) [(i)]);
335
336 /* if color resolving fails, assume transparency */
337 val = _ctk_css_color_value_resolve (_ctk_symbolic_color_get_css_value (stop->color),
338 provider,
339 ctk_css_style_get_value (style, CTK_CSS_PROPERTY_COLOR),
340 NULL((void*)0));
341 if (val)
342 {
343 rgba = *_ctk_css_rgba_value_get_rgba (val);
344 _ctk_css_value_unref (val);
345 }
346 else
347 {
348 rgba.red = rgba.green = rgba.blue = rgba.alpha = 0.0;
349 }
350
351 cairo_pattern_add_color_stop_rgba (pattern, stop->offset,
352 rgba.red, rgba.green,
353 rgba.blue, rgba.alpha);
354 }
355
356 return pattern;
357}
358
359static void
360append_number (GString *str,
361 double d,
362 const char *zero,
363 const char *half,
364 const char *one)
365{
366 if (zero && d == 0.0)
367 g_string_append (str, zero)(__builtin_constant_p (zero) ? __extension__ ({ const char * const
__val = (zero); g_string_append_len_inline (str, __val, (__val
!= ((void*)0)) ? (gssize) strlen (((__val) + !(__val))) : (gssize
) -1); }) : g_string_append_len_inline (str, zero, (gssize) -
1))
;
368 else if (half && d == 0.5)
369 g_string_append (str, half)(__builtin_constant_p (half) ? __extension__ ({ const char * const
__val = (half); g_string_append_len_inline (str, __val, (__val
!= ((void*)0)) ? (gssize) strlen (((__val) + !(__val))) : (gssize
) -1); }) : g_string_append_len_inline (str, half, (gssize) -
1))
;
370 else if (one && d == 1.0)
371 g_string_append (str, one)(__builtin_constant_p (one) ? __extension__ ({ const char * const
__val = (one); g_string_append_len_inline (str, __val, (__val
!= ((void*)0)) ? (gssize) strlen (((__val) + !(__val))) : (gssize
) -1); }) : g_string_append_len_inline (str, one, (gssize) -1
))
;
372 else
373 {
374 char buf[G_ASCII_DTOSTR_BUF_SIZE(29 + 10)];
375
376 g_ascii_dtostr (buf, sizeof (buf), d);
377 g_string_append (str, buf)(__builtin_constant_p (buf) ? __extension__ ({ const char * const
__val = (buf); g_string_append_len_inline (str, __val, (__val
!= ((void*)0)) ? (gssize) strlen (((__val) + !(__val))) : (gssize
) -1); }) : g_string_append_len_inline (str, buf, (gssize) -1
))
;
378 }
379}
380
381/**
382 * ctk_gradient_to_string:
383 * @gradient: the gradient to print
384 *
385 * Creates a string representation for @gradient that is suitable
386 * for using in CTK CSS files.
387 *
388 * Returns: A string representation for @gradient
389 *
390 * Deprecated: 3.8: #CtkGradient is deprecated.
391 **/
392char *
393ctk_gradient_to_string (CtkGradient *gradient)
394{
395 GString *str;
396 guint i;
397
398 g_return_val_if_fail (gradient != NULL, NULL)do { if ((gradient != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "gradient != NULL"); return
(((void*)0)); } } while (0)
;
399
400 str = g_string_new ("-ctk-gradient (");
401
402 if (gradient->radius0 == 0 && gradient->radius1 == 0)
403 {
404 g_string_append (str, "linear, ")(__builtin_constant_p ("linear, ") ? __extension__ ({ const char
* const __val = ("linear, "); g_string_append_len_inline (str
, __val, (__val != ((void*)0)) ? (gssize) strlen (((__val) + !
(__val))) : (gssize) -1); }) : g_string_append_len_inline (str
, "linear, ", (gssize) -1))
;
405 append_number (str, gradient->x0, "left", "center", "right");
406 g_string_append_c (str, ' ')g_string_append_c_inline (str, ' ');
407 append_number (str, gradient->y0, "top", "center", "bottom");
408 g_string_append (str, ", ")(__builtin_constant_p (", ") ? __extension__ ({ const char * const
__val = (", "); g_string_append_len_inline (str, __val, (__val
!= ((void*)0)) ? (gssize) strlen (((__val) + !(__val))) : (gssize
) -1); }) : g_string_append_len_inline (str, ", ", (gssize) -
1))
;
409 append_number (str, gradient->x1, "left", "center", "right");
410 g_string_append_c (str, ' ')g_string_append_c_inline (str, ' ');
411 append_number (str, gradient->y1, "top", "center", "bottom");
412 }
413 else
414 {
415 g_string_append (str, "radial, ")(__builtin_constant_p ("radial, ") ? __extension__ ({ const char
* const __val = ("radial, "); g_string_append_len_inline (str
, __val, (__val != ((void*)0)) ? (gssize) strlen (((__val) + !
(__val))) : (gssize) -1); }) : g_string_append_len_inline (str
, "radial, ", (gssize) -1))
;
416 append_number (str, gradient->x0, "left", "center", "right");
417 g_string_append_c (str, ' ')g_string_append_c_inline (str, ' ');
418 append_number (str, gradient->y0, "top", "center", "bottom");
419 g_string_append (str, ", ")(__builtin_constant_p (", ") ? __extension__ ({ const char * const
__val = (", "); g_string_append_len_inline (str, __val, (__val
!= ((void*)0)) ? (gssize) strlen (((__val) + !(__val))) : (gssize
) -1); }) : g_string_append_len_inline (str, ", ", (gssize) -
1))
;
420 append_number (str, gradient->radius0, NULL((void*)0), NULL((void*)0), NULL((void*)0));
421 g_string_append (str, ", ")(__builtin_constant_p (", ") ? __extension__ ({ const char * const
__val = (", "); g_string_append_len_inline (str, __val, (__val
!= ((void*)0)) ? (gssize) strlen (((__val) + !(__val))) : (gssize
) -1); }) : g_string_append_len_inline (str, ", ", (gssize) -
1))
;
422 append_number (str, gradient->x1, "left", "center", "right");
423 g_string_append_c (str, ' ')g_string_append_c_inline (str, ' ');
424 append_number (str, gradient->y1, "top", "center", "bottom");
425 g_string_append (str, ", ")(__builtin_constant_p (", ") ? __extension__ ({ const char * const
__val = (", "); g_string_append_len_inline (str, __val, (__val
!= ((void*)0)) ? (gssize) strlen (((__val) + !(__val))) : (gssize
) -1); }) : g_string_append_len_inline (str, ", ", (gssize) -
1))
;
426 append_number (str, gradient->radius1, NULL((void*)0), NULL((void*)0), NULL((void*)0));
427 }
428
429 for (i = 0; i < gradient->stops->len; i++)
430 {
431 ColorStop *stop;
432 char *s;
433
434 stop = &g_array_index (gradient->stops, ColorStop, i)(((ColorStop*) (void *) (gradient->stops)->data) [(i)]);
435
436 g_string_append (str, ", ")(__builtin_constant_p (", ") ? __extension__ ({ const char * const
__val = (", "); g_string_append_len_inline (str, __val, (__val
!= ((void*)0)) ? (gssize) strlen (((__val) + !(__val))) : (gssize
) -1); }) : g_string_append_len_inline (str, ", ", (gssize) -
1))
;
437
438 if (stop->offset == 0.0)
439 g_string_append (str, "from (")(__builtin_constant_p ("from (") ? __extension__ ({ const char
* const __val = ("from ("); g_string_append_len_inline (str,
__val, (__val != ((void*)0)) ? (gssize) strlen (((__val) + !
(__val))) : (gssize) -1); }) : g_string_append_len_inline (str
, "from (", (gssize) -1))
;
440 else if (stop->offset == 1.0)
441 g_string_append (str, "to (")(__builtin_constant_p ("to (") ? __extension__ ({ const char *
const __val = ("to ("); g_string_append_len_inline (str, __val
, (__val != ((void*)0)) ? (gssize) strlen (((__val) + !(__val
))) : (gssize) -1); }) : g_string_append_len_inline (str, "to ("
, (gssize) -1))
;
442 else
443 {
444 g_string_append (str, "color-stop (")(__builtin_constant_p ("color-stop (") ? __extension__ ({ const
char * const __val = ("color-stop ("); g_string_append_len_inline
(str, __val, (__val != ((void*)0)) ? (gssize) strlen (((__val
) + !(__val))) : (gssize) -1); }) : g_string_append_len_inline
(str, "color-stop (", (gssize) -1))
;
445 append_number (str, stop->offset, NULL((void*)0), NULL((void*)0), NULL((void*)0));
446 g_string_append (str, ", ")(__builtin_constant_p (", ") ? __extension__ ({ const char * const
__val = (", "); g_string_append_len_inline (str, __val, (__val
!= ((void*)0)) ? (gssize) strlen (((__val) + !(__val))) : (gssize
) -1); }) : g_string_append_len_inline (str, ", ", (gssize) -
1))
;
447 }
448
449 s = ctk_symbolic_color_to_string (stop->color);
450 g_string_append (str, s)(__builtin_constant_p (s) ? __extension__ ({ const char * const
__val = (s); g_string_append_len_inline (str, __val, (__val !=
((void*)0)) ? (gssize) strlen (((__val) + !(__val))) : (gssize
) -1); }) : g_string_append_len_inline (str, s, (gssize) -1))
;
451 g_free (s);
452
453 g_string_append (str, ")")(__builtin_constant_p (")") ? __extension__ ({ const char * const
__val = (")"); g_string_append_len_inline (str, __val, (__val
!= ((void*)0)) ? (gssize) strlen (((__val) + !(__val))) : (gssize
) -1); }) : g_string_append_len_inline (str, ")", (gssize) -1
))
;
454 }
455
456 g_string_append (str, ")")(__builtin_constant_p (")") ? __extension__ ({ const char * const
__val = (")"); g_string_append_len_inline (str, __val, (__val
!= ((void*)0)) ? (gssize) strlen (((__val) + !(__val))) : (gssize
) -1); }) : g_string_append_len_inline (str, ")", (gssize) -1
))
;
457
458 return g_string_free (str, FALSE)(__builtin_constant_p ((0)) ? (((0)) ? (g_string_free) ((str)
, ((0))) : g_string_free_and_steal (str)) : (g_string_free) (
(str), ((0))))
;
459}
460
461static CtkGradient *
462ctk_gradient_fade (CtkGradient *gradient,
463 double opacity)
464{
465 CtkGradient *faded;
466 guint i;
467
468 faded = g_slice_new (CtkGradient)((CtkGradient*) g_slice_alloc ((sizeof (CtkGradient) > 0 ?
sizeof (CtkGradient) : 1)))
;
469 faded->stops = g_array_new (FALSE(0), FALSE(0), sizeof (ColorStop));
470
471 faded->x0 = gradient->x0;
472 faded->y0 = gradient->y0;
473 faded->x1 = gradient->x1;
474 faded->y1 = gradient->y1;
475 faded->radius0 = gradient->radius0;
476 faded->radius1 = gradient->radius1;
477
478 faded->ref_count = 1;
479
480 for (i = 0; i < gradient->stops->len; i++)
481 {
482 CtkSymbolicColor *color;
483 ColorStop *stop;
484
485 stop = &g_array_index (gradient->stops, ColorStop, i)(((ColorStop*) (void *) (gradient->stops)->data) [(i)]);
486 color = ctk_symbolic_color_new_alpha (stop->color, opacity);
487 ctk_gradient_add_color_stop (faded, stop->offset, color);
488 ctk_symbolic_color_unref (color);
489 }
490
491 return faded;
492}
493
494CtkGradient *
495_ctk_gradient_transition (CtkGradient *start,
496 CtkGradient *end,
497 guint property_id G_GNUC_UNUSED__attribute__ ((__unused__)),
498 double progress)
499{
500 CtkGradient *gradient;
501 guint i;
502
503 g_return_val_if_fail (start != NULL, NULL)do { if ((start != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "start != NULL"); return
(((void*)0)); } } while (0)
;
504
505 if (end == NULL((void*)0))
506 return ctk_gradient_fade (start, 1.0 - CLAMP (progress, 0.0, 1.0)(((progress) > (1.0)) ? (1.0) : (((progress) < (0.0)) ?
(0.0) : (progress)))
);
507
508 if (start->stops->len != end->stops->len)
509 return NULL((void*)0);
510
511 /* check both are radial/linear */
512 if ((start->radius0 == 0 && start->radius1 == 0) != (end->radius0 == 0 && end->radius1 == 0))
513 return NULL((void*)0);
This statement is never executed
514
515 gradient = g_slice_new (CtkGradient)((CtkGradient*) g_slice_alloc ((sizeof (CtkGradient) > 0 ?
sizeof (CtkGradient) : 1)))
;
516 gradient->stops = g_array_new (FALSE(0), FALSE(0), sizeof (ColorStop));
517
518 gradient->x0 = (1 - progress) * start->x0 + progress * end->x0;
519 gradient->y0 = (1 - progress) * start->y0 + progress * end->y0;
520 gradient->x1 = (1 - progress) * start->x1 + progress * end->x1;
521 gradient->y1 = (1 - progress) * start->y1 + progress * end->y1;
522 gradient->radius0 = (1 - progress) * start->radius0 + progress * end->radius0;
523 gradient->radius1 = (1 - progress) * start->radius1 + progress * end->radius1;
524
525 gradient->ref_count = 1;
526
527 for (i = 0; i < start->stops->len; i++)
528 {
529 ColorStop *start_stop, *end_stop;
530 CtkSymbolicColor *color;
531 double offset;
532
533 start_stop = &g_array_index (start->stops, ColorStop, i)(((ColorStop*) (void *) (start->stops)->data) [(i)]);
534 end_stop = &g_array_index (end->stops, ColorStop, i)(((ColorStop*) (void *) (end->stops)->data) [(i)]);
535
536 offset = (1 - progress) * start_stop->offset + progress * end_stop->offset;
537 color = ctk_symbolic_color_new_mix (start_stop->color,
538 end_stop->color,
539 progress);
540 ctk_gradient_add_color_stop (gradient, offset, color);
541 ctk_symbolic_color_unref (color);
542 }
543
544 return gradient;
545}