Bug Summary

File:ctk/ctkpagesetup.c
Warning:line 860, column 37
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption

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 ctkpagesetup.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 -fcoverage-compilation-dir=/rootdir/ctk -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I .. -D G_LOG_DOMAIN="Ctk" -D G_LOG_USE_STRUCTURED=1 -D CTK_VERSION="3.25.5" -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/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/atk-1.0 -I /usr/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/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/gio-unix-2.0 -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 -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 -D PIC -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/ctk -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -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/2024-09-19-170505-43637-1 -x c ctkpagesetup.c
1/* CTK - The GIMP Toolkit
2 * ctkpagesetup.c: Page Setup
3 * Copyright (C) 2006, Red Hat, Inc.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include "config.h"
20
21#include "ctkpagesetup.h"
22#include "ctkprintutils.h"
23#include "ctkprintoperation.h" /* for CtkPrintError */
24#include "ctkintl.h"
25#include "ctktypebuiltins.h"
26
27/**
28 * SECTION:ctkpagesetup
29 * @Short_description: Stores page setup information
30 * @Title: CtkPageSetup
31 *
32 * A CtkPageSetup object stores the page size, orientation and margins.
33 * The idea is that you can get one of these from the page setup dialog
34 * and then pass it to the #CtkPrintOperation when printing.
35 * The benefit of splitting this out of the #CtkPrintSettings is that
36 * these affect the actual layout of the page, and thus need to be set
37 * long before user prints.
38 *
39 * ## Margins ## {#print-margins}
40 * The margins specified in this object are the “print margins”, i.e. the
41 * parts of the page that the printer cannot print on. These are different
42 * from the layout margins that a word processor uses; they are typically
43 * used to determine the minimal size for the layout
44 * margins.
45 *
46 * To obtain a #CtkPageSetup use ctk_page_setup_new() to get the defaults,
47 * or use ctk_print_run_page_setup_dialog() to show the page setup dialog
48 * and receive the resulting page setup.
49 *
50 * ## A page setup dialog
51 *
52 * |[<!-- language="C" -->
53 * static CtkPrintSettings *settings = NULL;
54 * static CtkPageSetup *page_setup = NULL;
55 *
56 * static void
57 * do_page_setup (void)
58 * {
59 * CtkPageSetup *new_page_setup;
60 *
61 * if (settings == NULL)
62 * settings = ctk_print_settings_new ();
63 *
64 * new_page_setup = ctk_print_run_page_setup_dialog (CTK_WINDOW (main_window),
65 * page_setup, settings);
66 *
67 * if (page_setup)
68 * g_object_unref (page_setup);
69 *
70 * page_setup = new_page_setup;
71 * }
72 * ]|
73 *
74 * Printing support was added in CTK+ 2.10.
75 */
76
77#define KEYFILE_GROUP_NAME"Page Setup" "Page Setup"
78
79typedef struct _CtkPageSetupClass CtkPageSetupClass;
80
81#define CTK_IS_PAGE_SETUP_CLASS(klass)(((__extension__ ({ GTypeClass *__class = (GTypeClass*) ((klass
)); GType __t = ((ctk_page_setup_get_type ())); gboolean __r;
if (!__class) __r = (0); else if (__class->g_type == __t)
__r = (!(0)); else __r = g_type_check_class_is_a (__class, __t
); __r; }))))
(G_TYPE_CHECK_CLASS_TYPE ((klass), CTK_TYPE_PAGE_SETUP)((__extension__ ({ GTypeClass *__class = (GTypeClass*) ((klass
)); GType __t = ((ctk_page_setup_get_type ())); gboolean __r;
if (!__class) __r = (0); else if (__class->g_type == __t)
__r = (!(0)); else __r = g_type_check_class_is_a (__class, __t
); __r; })))
)
82#define CTK_PAGE_SETUP_CLASS(klass)((((CtkPageSetupClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), ((ctk_page_setup_get_type ()))))))
(G_TYPE_CHECK_CLASS_CAST ((klass), CTK_TYPE_PAGE_SETUP, CtkPageSetupClass)(((CtkPageSetupClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), ((ctk_page_setup_get_type ())))))
)
83#define CTK_PAGE_SETUP_GET_CLASS(obj)((((CtkPageSetupClass*) (((GTypeInstance*) ((obj)))->g_class
))))
(G_TYPE_INSTANCE_GET_CLASS ((obj), CTK_TYPE_PAGE_SETUP, CtkPageSetupClass)(((CtkPageSetupClass*) (((GTypeInstance*) ((obj)))->g_class
)))
)
84
85struct _CtkPageSetup
86{
87 GObject parent_instance;
88
89 CtkPageOrientation orientation;
90 CtkPaperSize *paper_size;
91 /* These are stored in mm */
92 double top_margin, bottom_margin, left_margin, right_margin;
93};
94
95struct _CtkPageSetupClass
96{
97 GObjectClass parent_class;
98};
99
100G_DEFINE_TYPE (CtkPageSetup, ctk_page_setup, G_TYPE_OBJECT)static void ctk_page_setup_init (CtkPageSetup *self); static void
ctk_page_setup_class_init (CtkPageSetupClass *klass); static
GType ctk_page_setup_get_type_once (void); static gpointer ctk_page_setup_parent_class
= ((void*)0); static gint CtkPageSetup_private_offset; static
void ctk_page_setup_class_intern_init (gpointer klass) { ctk_page_setup_parent_class
= g_type_class_peek_parent (klass); if (CtkPageSetup_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &CtkPageSetup_private_offset
); ctk_page_setup_class_init ((CtkPageSetupClass*) klass); } __attribute__
((__unused__)) static inline gpointer ctk_page_setup_get_instance_private
(CtkPageSetup *self) { return (((gpointer) ((guint8*) (self)
+ (glong) (CtkPageSetup_private_offset)))); } GType ctk_page_setup_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_page_setup_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_page_setup_get_type_once (void
) { GType g_define_type_id = g_type_register_static_simple ((
(GType) ((20) << (2))), g_intern_static_string ("CtkPageSetup"
), sizeof (CtkPageSetupClass), (GClassInitFunc)(void (*)(void
)) ctk_page_setup_class_intern_init, sizeof (CtkPageSetup), (
GInstanceInitFunc)(void (*)(void)) ctk_page_setup_init, (GTypeFlags
) 0); { {{};} } return g_define_type_id; }
101
102static void
103ctk_page_setup_finalize (GObject *object)
104{
105 CtkPageSetup *setup = CTK_PAGE_SETUP (object)((((CtkPageSetup*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ctk_page_setup_get_type ()))))))
;
106
107 ctk_paper_size_free (setup->paper_size);
108
109 G_OBJECT_CLASS (ctk_page_setup_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_page_setup_parent_class)), (((GType) ((20) << (
2))))))))
->finalize (object);
110}
111
112static void
113ctk_page_setup_init (CtkPageSetup *setup)
114{
115 setup->paper_size = ctk_paper_size_new (NULL((void*)0));
116 setup->orientation = CTK_PAGE_ORIENTATION_PORTRAIT;
117 setup->top_margin = ctk_paper_size_get_default_top_margin (setup->paper_size, CTK_UNIT_MM);
118 setup->bottom_margin = ctk_paper_size_get_default_bottom_margin (setup->paper_size, CTK_UNIT_MM);
119 setup->left_margin = ctk_paper_size_get_default_left_margin (setup->paper_size, CTK_UNIT_MM);
120 setup->right_margin = ctk_paper_size_get_default_right_margin (setup->paper_size, CTK_UNIT_MM);
121}
122
123static void
124ctk_page_setup_class_init (CtkPageSetupClass *class)
125{
126 GObjectClass *gobject_class = (GObjectClass *)class;
127
128 gobject_class->finalize = ctk_page_setup_finalize;
129}
130
131/**
132 * ctk_page_setup_new:
133 *
134 * Creates a new #CtkPageSetup.
135 *
136 * Returns: a new #CtkPageSetup.
137 *
138 * Since: 2.10
139 */
140CtkPageSetup *
141ctk_page_setup_new (void)
142{
143 return g_object_new (CTK_TYPE_PAGE_SETUP(ctk_page_setup_get_type ()), NULL((void*)0));
144}
145
146/**
147 * ctk_page_setup_copy:
148 * @other: the #CtkPageSetup to copy
149 *
150 * Copies a #CtkPageSetup.
151 *
152 * Returns: (transfer full): a copy of @other
153 *
154 * Since: 2.10
155 */
156CtkPageSetup *
157ctk_page_setup_copy (CtkPageSetup *other)
158{
159 CtkPageSetup *copy;
160
161 copy = ctk_page_setup_new ();
162 copy->orientation = other->orientation;
163 ctk_paper_size_free (copy->paper_size);
164 copy->paper_size = ctk_paper_size_copy (other->paper_size);
165 copy->top_margin = other->top_margin;
166 copy->bottom_margin = other->bottom_margin;
167 copy->left_margin = other->left_margin;
168 copy->right_margin = other->right_margin;
169
170 return copy;
171}
172
173/**
174 * ctk_page_setup_get_orientation:
175 * @setup: a #CtkPageSetup
176 *
177 * Gets the page orientation of the #CtkPageSetup.
178 *
179 * Returns: the page orientation
180 *
181 * Since: 2.10
182 */
183CtkPageOrientation
184ctk_page_setup_get_orientation (CtkPageSetup *setup)
185{
186 return setup->orientation;
187}
188
189/**
190 * ctk_page_setup_set_orientation:
191 * @setup: a #CtkPageSetup
192 * @orientation: a #CtkPageOrientation value
193 *
194 * Sets the page orientation of the #CtkPageSetup.
195 *
196 * Since: 2.10
197 */
198void
199ctk_page_setup_set_orientation (CtkPageSetup *setup,
200 CtkPageOrientation orientation)
201{
202 setup->orientation = orientation;
203}
204
205/**
206 * ctk_page_setup_get_paper_size:
207 * @setup: a #CtkPageSetup
208 *
209 * Gets the paper size of the #CtkPageSetup.
210 *
211 * Returns: (transfer none): the paper size
212 *
213 * Since: 2.10
214 */
215CtkPaperSize *
216ctk_page_setup_get_paper_size (CtkPageSetup *setup)
217{
218 g_return_val_if_fail (CTK_IS_PAGE_SETUP (setup), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((setup)); GType __t = ((ctk_page_setup_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_PAGE_SETUP (setup)"); return (((void*)0)); } } while
(0)
;
219
220 return setup->paper_size;
221}
222
223/**
224 * ctk_page_setup_set_paper_size:
225 * @setup: a #CtkPageSetup
226 * @size: a #CtkPaperSize
227 *
228 * Sets the paper size of the #CtkPageSetup without
229 * changing the margins. See
230 * ctk_page_setup_set_paper_size_and_default_margins().
231 *
232 * Since: 2.10
233 */
234void
235ctk_page_setup_set_paper_size (CtkPageSetup *setup,
236 CtkPaperSize *size)
237{
238 CtkPaperSize *old_size;
239
240 g_return_if_fail (CTK_IS_PAGE_SETUP (setup))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((setup)); GType __t = ((ctk_page_setup_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_PAGE_SETUP (setup)"); return; } } while (0)
;
241 g_return_if_fail (size != NULL)do { if ((size != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "size != NULL"); return;
} } while (0)
;
242
243 old_size = setup->paper_size;
244
245 setup->paper_size = ctk_paper_size_copy (size);
246
247 if (old_size)
248 ctk_paper_size_free (old_size);
249}
250
251/**
252 * ctk_page_setup_set_paper_size_and_default_margins:
253 * @setup: a #CtkPageSetup
254 * @size: a #CtkPaperSize
255 *
256 * Sets the paper size of the #CtkPageSetup and modifies
257 * the margins according to the new paper size.
258 *
259 * Since: 2.10
260 */
261void
262ctk_page_setup_set_paper_size_and_default_margins (CtkPageSetup *setup,
263 CtkPaperSize *size)
264{
265 ctk_page_setup_set_paper_size (setup, size);
266 setup->top_margin = ctk_paper_size_get_default_top_margin (setup->paper_size, CTK_UNIT_MM);
267 setup->bottom_margin = ctk_paper_size_get_default_bottom_margin (setup->paper_size, CTK_UNIT_MM);
268 setup->left_margin = ctk_paper_size_get_default_left_margin (setup->paper_size, CTK_UNIT_MM);
269 setup->right_margin = ctk_paper_size_get_default_right_margin (setup->paper_size, CTK_UNIT_MM);
270}
271
272/**
273 * ctk_page_setup_get_top_margin:
274 * @setup: a #CtkPageSetup
275 * @unit: the unit for the return value
276 *
277 * Gets the top margin in units of @unit.
278 *
279 * Returns: the top margin
280 *
281 * Since: 2.10
282 */
283gdouble
284ctk_page_setup_get_top_margin (CtkPageSetup *setup,
285 CtkUnit unit)
286{
287 return _ctk_print_convert_from_mm (setup->top_margin, unit);
288}
289
290/**
291 * ctk_page_setup_set_top_margin:
292 * @setup: a #CtkPageSetup
293 * @margin: the new top margin in units of @unit
294 * @unit: the units for @margin
295 *
296 * Sets the top margin of the #CtkPageSetup.
297 *
298 * Since: 2.10
299 */
300void
301ctk_page_setup_set_top_margin (CtkPageSetup *setup,
302 gdouble margin,
303 CtkUnit unit)
304{
305 setup->top_margin = _ctk_print_convert_to_mm (margin, unit);
306}
307
308/**
309 * ctk_page_setup_get_bottom_margin:
310 * @setup: a #CtkPageSetup
311 * @unit: the unit for the return value
312 *
313 * Gets the bottom margin in units of @unit.
314 *
315 * Returns: the bottom margin
316 *
317 * Since: 2.10
318 */
319gdouble
320ctk_page_setup_get_bottom_margin (CtkPageSetup *setup,
321 CtkUnit unit)
322{
323 return _ctk_print_convert_from_mm (setup->bottom_margin, unit);
324}
325
326/**
327 * ctk_page_setup_set_bottom_margin:
328 * @setup: a #CtkPageSetup
329 * @margin: the new bottom margin in units of @unit
330 * @unit: the units for @margin
331 *
332 * Sets the bottom margin of the #CtkPageSetup.
333 *
334 * Since: 2.10
335 */
336void
337ctk_page_setup_set_bottom_margin (CtkPageSetup *setup,
338 gdouble margin,
339 CtkUnit unit)
340{
341 setup->bottom_margin = _ctk_print_convert_to_mm (margin, unit);
342}
343
344/**
345 * ctk_page_setup_get_left_margin:
346 * @setup: a #CtkPageSetup
347 * @unit: the unit for the return value
348 *
349 * Gets the left margin in units of @unit.
350 *
351 * Returns: the left margin
352 *
353 * Since: 2.10
354 */
355gdouble
356ctk_page_setup_get_left_margin (CtkPageSetup *setup,
357 CtkUnit unit)
358{
359 return _ctk_print_convert_from_mm (setup->left_margin, unit);
360}
361
362/**
363 * ctk_page_setup_set_left_margin:
364 * @setup: a #CtkPageSetup
365 * @margin: the new left margin in units of @unit
366 * @unit: the units for @margin
367 *
368 * Sets the left margin of the #CtkPageSetup.
369 *
370 * Since: 2.10
371 */
372void
373ctk_page_setup_set_left_margin (CtkPageSetup *setup,
374 gdouble margin,
375 CtkUnit unit)
376{
377 setup->left_margin = _ctk_print_convert_to_mm (margin, unit);
378}
379
380/**
381 * ctk_page_setup_get_right_margin:
382 * @setup: a #CtkPageSetup
383 * @unit: the unit for the return value
384 *
385 * Gets the right margin in units of @unit.
386 *
387 * Returns: the right margin
388 *
389 * Since: 2.10
390 */
391gdouble
392ctk_page_setup_get_right_margin (CtkPageSetup *setup,
393 CtkUnit unit)
394{
395 return _ctk_print_convert_from_mm (setup->right_margin, unit);
396}
397
398/**
399 * ctk_page_setup_set_right_margin:
400 * @setup: a #CtkPageSetup
401 * @margin: the new right margin in units of @unit
402 * @unit: the units for @margin
403 *
404 * Sets the right margin of the #CtkPageSetup.
405 *
406 * Since: 2.10
407 */
408void
409ctk_page_setup_set_right_margin (CtkPageSetup *setup,
410 gdouble margin,
411 CtkUnit unit)
412{
413 setup->right_margin = _ctk_print_convert_to_mm (margin, unit);
414}
415
416/**
417 * ctk_page_setup_get_paper_width:
418 * @setup: a #CtkPageSetup
419 * @unit: the unit for the return value
420 *
421 * Returns the paper width in units of @unit.
422 *
423 * Note that this function takes orientation, but
424 * not margins into consideration.
425 * See ctk_page_setup_get_page_width().
426 *
427 * Returns: the paper width.
428 *
429 * Since: 2.10
430 */
431gdouble
432ctk_page_setup_get_paper_width (CtkPageSetup *setup,
433 CtkUnit unit)
434{
435 if (setup->orientation == CTK_PAGE_ORIENTATION_PORTRAIT ||
436 setup->orientation == CTK_PAGE_ORIENTATION_REVERSE_PORTRAIT)
437 return ctk_paper_size_get_width (setup->paper_size, unit);
438 else
439 return ctk_paper_size_get_height (setup->paper_size, unit);
440}
441
442/**
443 * ctk_page_setup_get_paper_height:
444 * @setup: a #CtkPageSetup
445 * @unit: the unit for the return value
446 *
447 * Returns the paper height in units of @unit.
448 *
449 * Note that this function takes orientation, but
450 * not margins into consideration.
451 * See ctk_page_setup_get_page_height().
452 *
453 * Returns: the paper height.
454 *
455 * Since: 2.10
456 */
457gdouble
458ctk_page_setup_get_paper_height (CtkPageSetup *setup,
459 CtkUnit unit)
460{
461 if (setup->orientation == CTK_PAGE_ORIENTATION_PORTRAIT ||
462 setup->orientation == CTK_PAGE_ORIENTATION_REVERSE_PORTRAIT)
463 return ctk_paper_size_get_height (setup->paper_size, unit);
464 else
465 return ctk_paper_size_get_width (setup->paper_size, unit);
466}
467
468/**
469 * ctk_page_setup_get_page_width:
470 * @setup: a #CtkPageSetup
471 * @unit: the unit for the return value
472 *
473 * Returns the page width in units of @unit.
474 *
475 * Note that this function takes orientation and
476 * margins into consideration.
477 * See ctk_page_setup_get_paper_width().
478 *
479 * Returns: the page width.
480 *
481 * Since: 2.10
482 */
483gdouble
484ctk_page_setup_get_page_width (CtkPageSetup *setup,
485 CtkUnit unit)
486{
487 gdouble width;
488
489 width = ctk_page_setup_get_paper_width (setup, CTK_UNIT_MM);
490 if (setup->orientation == CTK_PAGE_ORIENTATION_PORTRAIT ||
491 setup->orientation == CTK_PAGE_ORIENTATION_REVERSE_PORTRAIT)
492 width -= setup->left_margin + setup->right_margin;
493 else
494 width -= setup->top_margin + setup->bottom_margin;
495
496 return _ctk_print_convert_from_mm (width, unit);
497}
498
499/**
500 * ctk_page_setup_get_page_height:
501 * @setup: a #CtkPageSetup
502 * @unit: the unit for the return value
503 *
504 * Returns the page height in units of @unit.
505 *
506 * Note that this function takes orientation and
507 * margins into consideration.
508 * See ctk_page_setup_get_paper_height().
509 *
510 * Returns: the page height.
511 *
512 * Since: 2.10
513 */
514gdouble
515ctk_page_setup_get_page_height (CtkPageSetup *setup,
516 CtkUnit unit)
517{
518 gdouble height;
519
520 height = ctk_page_setup_get_paper_height (setup, CTK_UNIT_MM);
521 if (setup->orientation == CTK_PAGE_ORIENTATION_PORTRAIT ||
522 setup->orientation == CTK_PAGE_ORIENTATION_REVERSE_PORTRAIT)
523 height -= setup->top_margin + setup->bottom_margin;
524 else
525 height -= setup->left_margin + setup->right_margin;
526
527 return _ctk_print_convert_from_mm (height, unit);
528}
529
530/**
531 * ctk_page_setup_load_file:
532 * @setup: a #CtkPageSetup
533 * @file_name: (type filename): the filename to read the page setup from
534 * @error: (allow-none): return location for an error, or %NULL
535 *
536 * Reads the page setup from the file @file_name.
537 * See ctk_page_setup_to_file().
538 *
539 * Returns: %TRUE on success
540 *
541 * Since: 2.14
542 */
543gboolean
544ctk_page_setup_load_file (CtkPageSetup *setup,
545 const gchar *file_name,
546 GError **error)
547{
548 gboolean retval = FALSE(0);
549 GKeyFile *key_file;
550
551 g_return_val_if_fail (CTK_IS_PAGE_SETUP (setup), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((setup)); GType __t = ((ctk_page_setup_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_PAGE_SETUP (setup)"); return ((0)); } } while (0)
;
552 g_return_val_if_fail (file_name != NULL, FALSE)do { if ((file_name != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "file_name != NULL"); return
((0)); } } while (0)
;
553
554 key_file = g_key_file_new ();
555
556 if (g_key_file_load_from_file (key_file, file_name, 0, error) &&
557 ctk_page_setup_load_key_file (setup, key_file, NULL((void*)0), error))
558 retval = TRUE(!(0));
559
560 g_key_file_free (key_file);
561
562 return retval;
563}
564
565/**
566 * ctk_page_setup_new_from_file:
567 * @file_name: (type filename): the filename to read the page setup from
568 * @error: (allow-none): return location for an error, or %NULL
569 *
570 * Reads the page setup from the file @file_name. Returns a
571 * new #CtkPageSetup object with the restored page setup,
572 * or %NULL if an error occurred. See ctk_page_setup_to_file().
573 *
574 * Returns: the restored #CtkPageSetup
575 *
576 * Since: 2.12
577 */
578CtkPageSetup *
579ctk_page_setup_new_from_file (const gchar *file_name,
580 GError **error)
581{
582 CtkPageSetup *setup = ctk_page_setup_new ();
583
584 if (!ctk_page_setup_load_file (setup, file_name, error))
585 {
586 g_object_unref (setup);
587 setup = NULL((void*)0);
588 }
589
590 return setup;
591}
592
593/* something like this should really be in gobject! */
594static guint
595string_to_enum (GType type,
596 const char *enum_string)
597{
598 GEnumClass *enum_class;
599 const GEnumValue *value;
600 guint retval = 0;
601
602 g_return_val_if_fail (enum_string != NULL, 0)do { if ((enum_string != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "enum_string != NULL"); return
(0); } } while (0)
;
603
604 enum_class = g_type_class_ref (type);
605 value = g_enum_get_value_by_nick (enum_class, enum_string);
606 if (value)
607 retval = value->value;
608
609 g_type_class_unref (enum_class);
610
611 return retval;
612}
613
614/**
615 * ctk_page_setup_load_key_file:
616 * @setup: a #CtkPageSetup
617 * @key_file: the #GKeyFile to retrieve the page_setup from
618 * @group_name: (allow-none): the name of the group in the key_file to read, or %NULL
619 * to use the default name “Page Setup”
620 * @error: (allow-none): return location for an error, or %NULL
621 *
622 * Reads the page setup from the group @group_name in the key file
623 * @key_file.
624 *
625 * Returns: %TRUE on success
626 *
627 * Since: 2.14
628 */
629gboolean
630ctk_page_setup_load_key_file (CtkPageSetup *setup,
631 GKeyFile *key_file,
632 const gchar *group_name,
633 GError **error)
634{
635 CtkPaperSize *paper_size;
636 gdouble top, bottom, left, right;
637 char *orientation = NULL((void*)0), *freeme = NULL((void*)0);
638 gboolean retval = FALSE(0);
639 GError *err = NULL((void*)0);
640
641 g_return_val_if_fail (CTK_IS_PAGE_SETUP (setup), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((setup)); GType __t = ((ctk_page_setup_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_PAGE_SETUP (setup)"); return ((0)); } } while (0)
;
642 g_return_val_if_fail (key_file != NULL, FALSE)do { if ((key_file != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "key_file != NULL"); return
((0)); } } while (0)
;
643
644 if (!group_name)
645 group_name = KEYFILE_GROUP_NAME"Page Setup";
646
647 if (!g_key_file_has_group (key_file, group_name))
648 {
649 g_set_error_literal (error,
650 CTK_PRINT_ERRORctk_print_error_quark (),
651 CTK_PRINT_ERROR_INVALID_FILE,
652 _("Not a valid page setup file")((char *) g_dgettext ("ctk30", "Not a valid page setup file")
)
);
653 goto out;
654 }
655
656#define GET_DOUBLE(kf, group, name, v) \
657 v = g_key_file_get_double (kf, group, name, &err); \
658 if (err != NULL((void*)0)) \
659 { \
660 g_propagate_error (error, err);\
661 goto out;\
662 }
663
664 GET_DOUBLE (key_file, group_name, "MarginTop", top);
665 GET_DOUBLE (key_file, group_name, "MarginBottom", bottom);
666 GET_DOUBLE (key_file, group_name, "MarginLeft", left);
667 GET_DOUBLE (key_file, group_name, "MarginRight", right);
668
669#undef GET_DOUBLE
670
671 paper_size = ctk_paper_size_new_from_key_file (key_file, group_name, &err);
672 if (!paper_size)
673 {
674 g_propagate_error (error, err);
675 goto out;
676 }
677
678 ctk_page_setup_set_paper_size (setup, paper_size);
679 ctk_paper_size_free (paper_size);
680
681 ctk_page_setup_set_top_margin (setup, top, CTK_UNIT_MM);
682 ctk_page_setup_set_bottom_margin (setup, bottom, CTK_UNIT_MM);
683 ctk_page_setup_set_left_margin (setup, left, CTK_UNIT_MM);
684 ctk_page_setup_set_right_margin (setup, right, CTK_UNIT_MM);
685
686 orientation = g_key_file_get_string (key_file, group_name,
687 "Orientation", NULL((void*)0));
688 if (orientation)
689 {
690 ctk_page_setup_set_orientation (setup,
691 string_to_enum (CTK_TYPE_PAGE_ORIENTATION(ctk_page_orientation_get_type ()),
692 orientation));
693 g_free (orientation);
694 }
695
696 retval = TRUE(!(0));
697
698out:
699 g_free (freeme);
700 return retval;
701}
702
703/**
704 * ctk_page_setup_new_from_key_file:
705 * @key_file: the #GKeyFile to retrieve the page_setup from
706 * @group_name: (allow-none): the name of the group in the key_file to read, or %NULL
707 * to use the default name “Page Setup”
708 * @error: (allow-none): return location for an error, or %NULL
709 *
710 * Reads the page setup from the group @group_name in the key file
711 * @key_file. Returns a new #CtkPageSetup object with the restored
712 * page setup, or %NULL if an error occurred.
713 *
714 * Returns: the restored #CtkPageSetup
715 *
716 * Since: 2.12
717 */
718CtkPageSetup *
719ctk_page_setup_new_from_key_file (GKeyFile *key_file,
720 const gchar *group_name,
721 GError **error)
722{
723 CtkPageSetup *setup = ctk_page_setup_new ();
724
725 if (!ctk_page_setup_load_key_file (setup, key_file, group_name, error))
726 {
727 g_object_unref (setup);
728 setup = NULL((void*)0);
729 }
730
731 return setup;
732}
733
734/**
735 * ctk_page_setup_to_file:
736 * @setup: a #CtkPageSetup
737 * @file_name: (type filename): the file to save to
738 * @error: (allow-none): return location for errors, or %NULL
739 *
740 * This function saves the information from @setup to @file_name.
741 *
742 * Returns: %TRUE on success
743 *
744 * Since: 2.12
745 */
746gboolean
747ctk_page_setup_to_file (CtkPageSetup *setup,
748 const char *file_name,
749 GError **error)
750{
751 GKeyFile *key_file;
752 gboolean retval = FALSE(0);
753 char *data = NULL((void*)0);
754 gsize len;
755
756 g_return_val_if_fail (CTK_IS_PAGE_SETUP (setup), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((setup)); GType __t = ((ctk_page_setup_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_PAGE_SETUP (setup)"); return ((0)); } } while (0)
;
757 g_return_val_if_fail (file_name != NULL, FALSE)do { if ((file_name != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "file_name != NULL"); return
((0)); } } while (0)
;
758
759 key_file = g_key_file_new ();
760 ctk_page_setup_to_key_file (setup, key_file, NULL((void*)0));
761
762 data = g_key_file_to_data (key_file, &len, error);
763 if (!data)
764 goto out;
765
766 retval = g_file_set_contents (file_name, data, len, error);
767
768out:
769 g_key_file_free (key_file);
770 g_free (data);
771
772 return retval;
773}
774
775/* something like this should really be in gobject! */
776static char *
777enum_to_string (GType type,
778 guint enum_value)
779{
780 GEnumClass *enum_class;
781 GEnumValue *value;
782 char *retval = NULL((void*)0);
783
784 enum_class = g_type_class_ref (type);
785
786 value = g_enum_get_value (enum_class, enum_value);
787 if (value)
788 retval = g_strdup (value->value_nick)g_strdup_inline (value->value_nick);
789
790 g_type_class_unref (enum_class);
791
792 return retval;
793}
794
795/**
796 * ctk_page_setup_to_key_file:
797 * @setup: a #CtkPageSetup
798 * @key_file: the #GKeyFile to save the page setup to
799 * @group_name: (nullable): the group to add the settings to in @key_file,
800 * or %NULL to use the default name “Page Setup”
801 *
802 * This function adds the page setup from @setup to @key_file.
803 *
804 * Since: 2.12
805 */
806void
807ctk_page_setup_to_key_file (CtkPageSetup *setup,
808 GKeyFile *key_file,
809 const gchar *group_name)
810{
811 CtkPaperSize *paper_size;
812 char *orientation;
813
814 g_return_if_fail (CTK_IS_PAGE_SETUP (setup))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((setup)); GType __t = ((ctk_page_setup_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_PAGE_SETUP (setup)"); return; } } while (0)
;
815 g_return_if_fail (key_file != NULL)do { if ((key_file != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "key_file != NULL"); return
; } } while (0)
;
816
817 if (!group_name)
818 group_name = KEYFILE_GROUP_NAME"Page Setup";
819
820 paper_size = ctk_page_setup_get_paper_size (setup);
821 g_assert (paper_size != NULL)do { if (paper_size != ((void*)0)) ; else g_assertion_message_expr
("Ctk", "ctkpagesetup.c", 821, ((const char*) (__func__)), "paper_size != NULL"
); } while (0)
;
822
823 ctk_paper_size_to_key_file (paper_size, key_file, group_name);
824
825 g_key_file_set_double (key_file, group_name,
826 "MarginTop", ctk_page_setup_get_top_margin (setup, CTK_UNIT_MM));
827 g_key_file_set_double (key_file, group_name,
828 "MarginBottom", ctk_page_setup_get_bottom_margin (setup, CTK_UNIT_MM));
829 g_key_file_set_double (key_file, group_name,
830 "MarginLeft", ctk_page_setup_get_left_margin (setup, CTK_UNIT_MM));
831 g_key_file_set_double (key_file, group_name,
832 "MarginRight", ctk_page_setup_get_right_margin (setup, CTK_UNIT_MM));
833
834 orientation = enum_to_string (CTK_TYPE_PAGE_ORIENTATION(ctk_page_orientation_get_type ()),
835 ctk_page_setup_get_orientation (setup));
836 g_key_file_set_string (key_file, group_name,
837 "Orientation", orientation);
838 g_free (orientation);
839}
840
841/**
842 * ctk_page_setup_to_gvariant:
843 * @setup: a #CtkPageSetup
844 *
845 * Serialize page setup to an a{sv} variant.
846 *
847 * Return: (transfer none): a new, floating, #GVariant
848 *
849 * Since: 3.22
850 */
851GVariant *
852ctk_page_setup_to_gvariant (CtkPageSetup *setup)
853{
854 CtkPaperSize *paper_size;
855 GVariant *variant;
856 int i;
857 GVariantBuilder builder;
858 char *orientation;
859
860 g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT((const GVariantType *) "a{sv}"));
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
861
862 paper_size = ctk_page_setup_get_paper_size (setup);
863
864 variant = g_variant_ref_sink (ctk_paper_size_to_gvariant (paper_size));
865 for (i = 0; i < g_variant_n_children (variant); i++)
866 g_variant_builder_add_value (&builder, g_variant_get_child_value (variant, i));
867 g_variant_unref (variant);
868
869 g_variant_builder_add (&builder, "{sv}", "MarginTop", g_variant_new_double (ctk_page_setup_get_top_margin (setup, CTK_UNIT_MM)));
870 g_variant_builder_add (&builder, "{sv}", "MarginBottom", g_variant_new_double (ctk_page_setup_get_bottom_margin (setup, CTK_UNIT_MM)));
871 g_variant_builder_add (&builder, "{sv}", "MarginLeft", g_variant_new_double (ctk_page_setup_get_left_margin (setup, CTK_UNIT_MM)));
872 g_variant_builder_add (&builder, "{sv}", "MarginRight", g_variant_new_double (ctk_page_setup_get_right_margin (setup, CTK_UNIT_MM)));
873
874 orientation = enum_to_string (CTK_TYPE_PAGE_ORIENTATION(ctk_page_orientation_get_type ()),
875 ctk_page_setup_get_orientation (setup));
876 g_variant_builder_add (&builder, "{sv}", "Orientation", g_variant_new_take_string (orientation));
877
878 return g_variant_builder_end (&builder);
879}
880
881/**
882 * ctk_page_setup_new_from_gvariant:
883 * @variant: an a{sv} #GVariant
884 *
885 * Desrialize a page setup from an a{sv} variant in
886 * the format produced by ctk_page_setup_to_gvariant().
887 *
888 * Returns: (transfer full): a new #CtkPageSetup object
889 *
890 * Since: 3.22
891 */
892CtkPageSetup *
893ctk_page_setup_new_from_gvariant (GVariant *variant)
894{
895 CtkPageSetup *setup;
896 const char *orientation;
897 gdouble margin;
898 CtkPaperSize *paper_size;
899
900 g_return_val_if_fail (g_variant_is_of_type (variant, G_VARIANT_TYPE_VARDICT), NULL)do { if ((g_variant_is_of_type (variant, ((const GVariantType
*) "a{sv}")))) { } else { g_return_if_fail_warning ("Ctk", (
(const char*) (__func__)), "g_variant_is_of_type (variant, G_VARIANT_TYPE_VARDICT)"
); return (((void*)0)); } } while (0)
;
901
902 setup = ctk_page_setup_new ();
903
904 paper_size = ctk_paper_size_new_from_gvariant (variant);
905 if (paper_size)
906 {
907 ctk_page_setup_set_paper_size (setup, paper_size);
908 ctk_paper_size_free (paper_size);
909 }
910
911 if (g_variant_lookup (variant, "MarginTop", "d", &margin))
912 ctk_page_setup_set_top_margin (setup, margin, CTK_UNIT_MM);
913 if (g_variant_lookup (variant, "MarginBottom", "d", &margin))
914 ctk_page_setup_set_bottom_margin (setup, margin, CTK_UNIT_MM);
915 if (g_variant_lookup (variant, "MarginLeft", "d", &margin))
916 ctk_page_setup_set_left_margin (setup, margin, CTK_UNIT_MM);
917 if (g_variant_lookup (variant, "MarginRight", "d", &margin))
918 ctk_page_setup_set_right_margin (setup, margin, CTK_UNIT_MM);
919
920 if (g_variant_lookup (variant, "Orientation", "&s", &orientation))
921 ctk_page_setup_set_orientation (setup, string_to_enum (CTK_TYPE_PAGE_ORIENTATION(ctk_page_orientation_get_type ()),
922 orientation));
923
924 return setup;
925}