Bug Summary

File:src/eoc-print-preview.c
Warning:line 788, column 3
2nd function call argument is an uninitialized value

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 eoc-print-preview.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/src -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I .. -I . -I .. -I ../jpegutils -I ../cut-n-paste/toolbar-editor -D G_LOG_DOMAIN="EOC" -D EOC_DATA_DIR="/usr/share/eoc" -D EOC_LOCALE_DIR="/usr/share/locale" -D EOC_PLUGIN_DIR="/usr/lib/eoc/plugins" -D LIBDIR="/usr/lib" -I /usr/include/ctk-3.0 -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/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -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/cafe-desktop-2.0 -I /usr/include/startup-notification-1.0 -I /usr/include/dconf -I /usr/include/ctk-3.0/unix-print -I /usr/local/include/libbean-1.0 -I /usr/include/gobject-introspection-1.0 -I /usr/include/exempi-2.0 -I /usr/include/librsvg-2.0 -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/13/../../../../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/src -ferror-limit 19 -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-08-05-200213-32259-1 -x c eoc-print-preview.c
1/* Eye Of CAFE -- Print Preview Widget
2 *
3 * Copyright (C) 2006-2008 The Free Software Foundation
4 *
5 * Author: Claudio Saavedra <csaavedra@gnome.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21
22#include <ctk/ctk.h>
23#include <cairo.h>
24#include <cdk/cdkkeysyms.h>
25
26#include "eoc-image.h"
27#include "eoc-print-preview.h"
28
29struct _EocPrintPreviewPrivate {
30 CtkWidget *area;
31 GdkPixbuf *image;
32 GdkPixbuf *image_scaled;
33
34 /* The surface to set to the cairo context, created from the image */
35 cairo_surface_t *surface;
36
37 /* Flag whether we have to create surface */
38 gboolean flag_create_surface;
39
40 /* the alignment of the image in the page */
41 gfloat image_x_align, image_y_align;
42
43 /* real paper size, in inches */
44 gfloat p_width, p_height;
45
46 /* page margins, in inches */
47 gfloat l_margin, r_margin, t_margin, b_margin;
48
49 /* page margins, relatives to the widget size */
50 gint l_rmargin, r_rmargin, t_rmargin, b_rmargin;
51
52 /* image width, relative to the widget size */
53 gint r_width, r_height;
54
55 /* scale of the image, as defined by the user */
56 gfloat i_scale;
57
58 /* scale of the page, relative to the widget size */
59 gfloat p_scale;
60
61 /* whether we are currently grabbing the image */
62 gboolean grabbed;
63
64 /* the last cursor position */
65 gdouble cursorx, cursory;
66
67 /* if we reject to move the image,
68 store the delta here */
69 gdouble r_dx, r_dy;
70};
71
72/* Signal IDs */
73enum {
74 SIGNAL_IMAGE_MOVED,
75 SIGNAL_LAST
76};
77
78static guint preview_signals [SIGNAL_LAST] = { 0 };
79
80enum {
81 PROP_0,
82 PROP_IMAGE,
83 PROP_IMAGE_X_ALIGN,
84 PROP_IMAGE_Y_ALIGN,
85 PROP_IMAGE_SCALE,
86 PROP_PAPER_WIDTH,
87 PROP_PAPER_HEIGHT,
88 PROP_PAGE_LEFT_MARGIN,
89 PROP_PAGE_RIGHT_MARGIN,
90 PROP_PAGE_TOP_MARGIN,
91 PROP_PAGE_BOTTOM_MARGIN
92};
93
94G_DEFINE_TYPE_WITH_PRIVATE (EocPrintPreview, eoc_print_preview, CTK_TYPE_ASPECT_FRAME)static void eoc_print_preview_init (EocPrintPreview *self); static
void eoc_print_preview_class_init (EocPrintPreviewClass *klass
); static GType eoc_print_preview_get_type_once (void); static
gpointer eoc_print_preview_parent_class = ((void*)0); static
gint EocPrintPreview_private_offset; static void eoc_print_preview_class_intern_init
(gpointer klass) { eoc_print_preview_parent_class = g_type_class_peek_parent
(klass); if (EocPrintPreview_private_offset != 0) g_type_class_adjust_private_offset
(klass, &EocPrintPreview_private_offset); eoc_print_preview_class_init
((EocPrintPreviewClass*) klass); } __attribute__ ((__unused__
)) static inline gpointer eoc_print_preview_get_instance_private
(EocPrintPreview *self) { return (((gpointer) ((guint8*) (self
) + (glong) (EocPrintPreview_private_offset)))); } GType eoc_print_preview_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
= eoc_print_preview_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 eoc_print_preview_get_type_once (
void) { GType g_define_type_id = g_type_register_static_simple
((ctk_aspect_frame_get_type ()), g_intern_static_string ("EocPrintPreview"
), sizeof (EocPrintPreviewClass), (GClassInitFunc)(void (*)(void
)) eoc_print_preview_class_intern_init, sizeof (EocPrintPreview
), (GInstanceInitFunc)(void (*)(void)) eoc_print_preview_init
, (GTypeFlags) 0); { {{ EocPrintPreview_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (EocPrintPreviewPrivate)); };} } return
g_define_type_id; }
95
96static void eoc_print_preview_draw (EocPrintPreview *preview, cairo_t *cr);
97static void eoc_print_preview_finalize (GObject *object);
98static void update_relative_sizes (EocPrintPreview *preview);
99static void create_surface (EocPrintPreview *preview);
100static void create_image_scaled (EocPrintPreview *preview);
101static gboolean create_surface_when_idle (EocPrintPreview *preview);
102
103static void
104eoc_print_preview_get_property (GObject *object,
105 guint prop_id,
106 GValue *value,
107 GParamSpec *pspec)
108{
109 EocPrintPreviewPrivate *priv = EOC_PRINT_PREVIEW (object)((((EocPrintPreview*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((eoc_print_preview_get_type ()))))))
->priv;
110
111 switch (prop_id) {
112 case PROP_IMAGE:
113 g_value_set_object (value, priv->image);
114 break;
115 case PROP_IMAGE_X_ALIGN:
116 g_value_set_float (value, priv->image_x_align);
117 break;
118 case PROP_IMAGE_Y_ALIGN:
119 g_value_set_float (value, priv->image_y_align);
120 break;
121 case PROP_IMAGE_SCALE:
122 g_value_set_float (value, priv->i_scale);
123 break;
124 case PROP_PAPER_WIDTH:
125 g_value_set_float (value, priv->p_width);
126 break;
127 case PROP_PAPER_HEIGHT:
128 g_value_set_float (value, priv->p_height);
129 break;
130 case PROP_PAGE_LEFT_MARGIN:
131 g_value_set_float (value, priv->l_margin);
132 break;
133 case PROP_PAGE_RIGHT_MARGIN:
134 g_value_set_float (value, priv->r_margin);
135 break;
136 case PROP_PAGE_TOP_MARGIN:
137 g_value_set_float (value, priv->t_margin);
138 break;
139 case PROP_PAGE_BOTTOM_MARGIN:
140 g_value_set_float (value, priv->b_margin);
141 break;
142 default:
143 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "eoc-print-preview.c", 143, ("property"), _glib__property_id
, _glib__pspec->name, g_type_name ((((((GTypeClass*) (((GTypeInstance
*) (_glib__pspec))->g_class))->g_type)))), (g_type_name
((((((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
144 }
145}
146
147static void
148eoc_print_preview_set_property (GObject *object,
149 guint prop_id,
150 const GValue *value,
151 GParamSpec *pspec)
152{
153 EocPrintPreviewPrivate *priv = EOC_PRINT_PREVIEW (object)((((EocPrintPreview*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((eoc_print_preview_get_type ()))))))
->priv;
154 gboolean paper_size_changed = FALSE(0);
155
156 switch (prop_id) {
157 case PROP_IMAGE:
158 if (priv->image) {
159 g_object_unref (priv->image);
160 }
161 priv->image = GDK_PIXBUF (g_value_dup_object (value))((((GdkPixbuf*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((g_value_dup_object (value))), ((gdk_pixbuf_get_type ()))
))))
;
162
163 if (priv->image_scaled) {
164 g_object_unref (priv->image_scaled);
165 priv->image_scaled = NULL((void*)0);
166 }
167
168 priv->flag_create_surface = TRUE(!(0));
169 break;
170 case PROP_IMAGE_X_ALIGN:
171 priv->image_x_align = g_value_get_float (value);
172 break;
173 case PROP_IMAGE_Y_ALIGN:
174 priv->image_y_align = g_value_get_float (value);
175 break;
176 case PROP_IMAGE_SCALE:
177 priv->i_scale = g_value_get_float (value);
178 priv->flag_create_surface = TRUE(!(0));
179 break;
180 case PROP_PAPER_WIDTH:
181 priv->p_width = g_value_get_float (value);
182 paper_size_changed = TRUE(!(0));
183 break;
184 case PROP_PAPER_HEIGHT:
185 priv->p_height = g_value_get_float (value);
186 paper_size_changed = TRUE(!(0));
187 break;
188 case PROP_PAGE_LEFT_MARGIN:
189 priv->l_margin = g_value_get_float (value);
190 break;
191 case PROP_PAGE_RIGHT_MARGIN:
192 priv->r_margin = g_value_get_float (value);
193 break;
194 case PROP_PAGE_TOP_MARGIN:
195 priv->t_margin = g_value_get_float (value);
196 break;
197 case PROP_PAGE_BOTTOM_MARGIN:
198 priv->b_margin = g_value_get_float (value);
199 break;
200 default:
201 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "eoc-print-preview.c", 201, ("property"), _glib__property_id
, _glib__pspec->name, g_type_name ((((((GTypeClass*) (((GTypeInstance
*) (_glib__pspec))->g_class))->g_type)))), (g_type_name
((((((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
202 }
203
204 if (paper_size_changed) {
205 g_object_set (object,
206 "ratio", priv->p_width/priv->p_height,
207 NULL((void*)0));
208 }
209
210 update_relative_sizes (EOC_PRINT_PREVIEW (object)((((EocPrintPreview*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((eoc_print_preview_get_type ()))))))
);
211 ctk_widget_queue_draw (priv->area);
212}
213
214static void
215eoc_print_preview_class_init (EocPrintPreviewClass *klass)
216{
217 GObjectClass *gobject_class;
218
219 gobject_class = (GObjectClass*) klass;
220
221 gobject_class->get_property = eoc_print_preview_get_property;
222 gobject_class->set_property = eoc_print_preview_set_property;
223 gobject_class->finalize = eoc_print_preview_finalize;
224
225/**
226 * EocPrintPreview:image:
227 *
228 * The "image" property defines the image that is previewed
229 * in the widget.
230 */
231 g_object_class_install_property (gobject_class,
232 PROP_IMAGE,
233 g_param_spec_object ("image",
234 "Image to show in the preview",
235 "",
236 G_TYPE_OBJECT((GType) ((20) << (2))),
237 G_PARAM_READWRITE));
238
239/**
240 * EocPrintPreview:image-x-align:
241 *
242 * The "image-x-align" property defines the horizontal alignment
243 * of the image in the widget.
244 */
245 g_object_class_install_property (gobject_class,
246 PROP_IMAGE_X_ALIGN,
247 g_param_spec_float ("image-x-align",
248 "Horizontal alignment for the image",
249 "",
250 0,
251 1,
252 0.5,
253 G_PARAM_READWRITE));
254
255/**
256 * EocPrintPreview:image-y-align:
257 *
258 * The "image-y-align" property defines the horizontal alignment
259 * of the image in the widget.
260 */
261 g_object_class_install_property (gobject_class,
262 PROP_IMAGE_Y_ALIGN,
263 g_param_spec_float ("image-y-align",
264 "Vertical alignment for the image",
265 "",
266 0,
267 1,
268 0.5,
269 G_PARAM_READWRITE));
270
271/**
272 * EocPrintPreview:image-scale:
273 *
274 * The "image-scale" property defines the scaling of the image
275 * that the user wants for the printing.
276 */
277 g_object_class_install_property (gobject_class,
278 PROP_IMAGE_SCALE,
279 g_param_spec_float ("image-scale",
280 "The scale for the image",
281 "",
282 0,
283 1,
284 1,
285 G_PARAM_READWRITE));
286
287/**
288 * EocPrintPreview:paper-width:
289 *
290 * The width of the previewed paper, in inches.
291 */
292 g_object_class_install_property (gobject_class,
293 PROP_PAPER_WIDTH,
294 g_param_spec_float ("paper-width",
295 "Real paper width in inches",
296 "",
297 0,
298 100,
299 8.5,
300 G_PARAM_READWRITE));
301
302/**
303 * EocPrintPreview:paper-height:
304 *
305 * The height of the previewed paper, in inches.
306 */
307 g_object_class_install_property (gobject_class,
308 PROP_PAPER_HEIGHT,
309 g_param_spec_float ("paper-height",
310 "Real paper height in inches",
311 "",
312 0,
313 200,
314 11,
315 G_PARAM_READWRITE));
316
317/**
318 * EocPrintPreview:page-left-margin:
319 *
320 * The size of the page's left margin, in inches.
321 */
322 g_object_class_install_property (gobject_class,
323 PROP_PAGE_LEFT_MARGIN,
324 g_param_spec_float ("page-left-margin",
325 "Left margin of the page in inches",
326 "",
327 0,
328 100,
329 0.25,
330 G_PARAM_READWRITE));
331
332/**
333 * EocPrintPreview:page-right-margin:
334 *
335 * The size of the page's right margin, in inches.
336 */
337 g_object_class_install_property (gobject_class,
338 PROP_PAGE_RIGHT_MARGIN,
339 g_param_spec_float ("page-right-margin",
340 "Right margin of the page in inches",
341 "",
342 0,
343 200,
344 0.25,
345 G_PARAM_READWRITE));
346/**
347 * EocPrintPreview:page-top-margin:
348 *
349 * The size of the page's top margin, in inches.
350 */
351 g_object_class_install_property (gobject_class,
352 PROP_PAGE_TOP_MARGIN,
353 g_param_spec_float ("page-top-margin",
354 "Top margin of the page in inches",
355 "",
356 0,
357 100,
358 0.25,
359 G_PARAM_READWRITE));
360
361/**
362 * EocPrintPreview:page-bottom-margin:
363 *
364 * The size of the page's bottom margin, in inches.
365 */
366 g_object_class_install_property (gobject_class,
367 PROP_PAGE_BOTTOM_MARGIN,
368 g_param_spec_float ("page-bottom-margin",
369 "Bottom margin of the page in inches",
370 "",
371 0,
372 200,
373 0.56,
374 G_PARAM_READWRITE));
375
376/**
377 * EocPrintPreview::image-moved:
378 * @preview: the object which received the signal
379 *
380 * The #EocPrintPreview::image-moved signal is emitted when the position
381 * of the image is changed.
382 */
383 preview_signals [SIGNAL_IMAGE_MOVED] =
384 g_signal_new ("image_moved",
385 G_TYPE_FROM_CLASS (gobject_class)(((GTypeClass*) (gobject_class))->g_type),
386 G_SIGNAL_RUN_FIRST, 0, NULL((void*)0), NULL((void*)0),
387 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE((GType) ((1) << (2))),
388 0, NULL((void*)0));
389}
390
391static void
392eoc_print_preview_finalize (GObject *object)
393{
394 EocPrintPreviewPrivate *priv;
395
396 priv = EOC_PRINT_PREVIEW (object)((((EocPrintPreview*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((eoc_print_preview_get_type ()))))))
->priv;
397
398 if (priv->image) {
399 g_object_unref (priv->image);
400 priv->image = NULL((void*)0);
401 }
402
403 if (priv->image_scaled) {
404 g_object_unref (priv->image_scaled);
405 priv->image_scaled = NULL((void*)0);
406 }
407
408 if (priv->surface) {
409 cairo_surface_destroy (priv->surface);
410 priv->surface = NULL((void*)0);
411 }
412
413 G_OBJECT_CLASS (eoc_print_preview_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((eoc_print_preview_parent_class)), (((GType) ((20) <<
(2))))))))
->finalize (object);
414}
415
416static void
417eoc_print_preview_init (EocPrintPreview *preview)
418{
419 EocPrintPreviewPrivate *priv;
420 gfloat ratio;
421
422 priv = preview->priv = eoc_print_preview_get_instance_private (preview);
423
424 priv->area = CTK_WIDGET (ctk_drawing_area_new ())((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_drawing_area_new ())), ((ctk_widget_get_type ())))))
)
;
425
426 ctk_container_add (CTK_CONTAINER (preview)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((preview)), ((ctk_container_get_type ()))))))
, priv->area);
427
428 priv->p_width = 8.5;
429 priv->p_height = 11.0;
430
431 ratio = priv->p_width/priv->p_height;
432
433 ctk_aspect_frame_set (CTK_ASPECT_FRAME (preview)((((CtkAspectFrame*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((preview)), ((ctk_aspect_frame_get_type ()))))))
,
434 0.5, 0.5, ratio, FALSE(0));
435
436 priv->image = NULL((void*)0);
437 priv->image_scaled = NULL((void*)0);
438 priv->image_x_align = 0.5;
439 priv->image_y_align = 0.5;
440 priv->i_scale = 1;
441
442 priv->surface = NULL((void*)0);
443 priv->flag_create_surface = TRUE(!(0));
444
445 priv->p_scale = 0;
446
447 priv->l_margin = 0.25;
448 priv->r_margin = 0.25;
449 priv->t_margin = 0.25;
450 priv->b_margin = 0.56;
451
452 priv->grabbed = FALSE(0);
453 priv->cursorx = 0;
454 priv->cursory = 0;
455 priv->r_dx = 0;
456 priv->r_dy = 0;
457}
458
459static gboolean button_press_event_cb (CtkWidget *widget, CdkEventButton *bev, gpointer user_data);
460static gboolean button_release_event_cb (CtkWidget *widget, CdkEventButton *bev, gpointer user_data);
461static gboolean motion_notify_event_cb (CtkWidget *widget, CdkEventMotion *mev, gpointer user_data);
462static gboolean key_press_event_cb (CtkWidget *widget, CdkEventKey *event, gpointer user_data);
463
464static gboolean draw_cb (CtkDrawingArea *drawing_area, cairo_t *cr, gpointer user_data);
465static void size_allocate_cb (CtkWidget *widget, CtkAllocation *allocation, gpointer user_data);
466
467/**
468 * eoc_print_preview_new_with_pixbuf:
469 * @pixbuf: a #GdkPixbuf
470 *
471 * Creates a new #EocPrintPreview widget, and sets the #GdkPixbuf to preview
472 * on it.
473 *
474 * Returns: A new #EocPrintPreview widget.
475 **/
476CtkWidget *
477eoc_print_preview_new_with_pixbuf (GdkPixbuf *pixbuf)
478{
479 EocPrintPreview *preview;
480
481 g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((pixbuf)); GType __t = ((gdk_pixbuf_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 ("EOC", ((const char*) (__func__
)), "GDK_IS_PIXBUF (pixbuf)"); return (((void*)0)); } } while
(0)
;
482
483 preview = EOC_PRINT_PREVIEW (eoc_print_preview_new ())((((EocPrintPreview*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((eoc_print_preview_new ())), ((eoc_print_preview_get_type
()))))))
;
484
485 preview->priv->image = g_object_ref (pixbuf)((__typeof__ (pixbuf)) (g_object_ref) (pixbuf));
486
487 update_relative_sizes (preview);
488
489 return CTK_WIDGET (preview)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((preview)), ((ctk_widget_get_type ()))))))
;
490}
491
492/**
493 * eoc_print_preview_new:
494 *
495 * Creates a new #EocPrintPreview widget, setting it to the default values,
496 * and leaving the page empty. You still need to set the #EocPrintPreview:image
497 * property to make it useful.
498 *
499 * Returns: A new and empty #EocPrintPreview widget.
500 **/
501CtkWidget *
502eoc_print_preview_new (void)
503{
504 EocPrintPreview *preview;
505 CtkWidget *area;
506
507 preview = g_object_new (EOC_TYPE_PRINT_PREVIEW(eoc_print_preview_get_type ()), NULL((void*)0));
508
509 area = preview->priv->area;
510
511 ctk_widget_set_events (area,
512 CDK_EXPOSURE_MASK |
513 CDK_POINTER_MOTION_MASK |
514 CDK_BUTTON_PRESS_MASK |
515 CDK_BUTTON_RELEASE_MASK |
516 CDK_KEY_PRESS_MASK);
517
518 g_object_set (G_OBJECT (area)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((area)), (((GType) ((20) << (2))))))))
,
519 "can-focus", TRUE(!(0)),
520 NULL((void*)0));
521
522/* update_relative_sizes (preview); */
523
524 g_signal_connect (G_OBJECT (area),g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((area)), (((GType) ((20) << (2)))))
)))), ("draw"), (((GCallback) (draw_cb))), (preview), ((void*
)0), (GConnectFlags) 0)
525 "draw", G_CALLBACK (draw_cb),g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((area)), (((GType) ((20) << (2)))))
)))), ("draw"), (((GCallback) (draw_cb))), (preview), ((void*
)0), (GConnectFlags) 0)
526 preview)g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((area)), (((GType) ((20) << (2)))))
)))), ("draw"), (((GCallback) (draw_cb))), (preview), ((void*
)0), (GConnectFlags) 0)
;
527
528 g_signal_connect (G_OBJECT (area), "motion-notify-event",g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((area)), (((GType) ((20) << (2)))))
)))), ("motion-notify-event"), (((GCallback) (motion_notify_event_cb
))), (preview), ((void*)0), (GConnectFlags) 0)
529 G_CALLBACK (motion_notify_event_cb), preview)g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((area)), (((GType) ((20) << (2)))))
)))), ("motion-notify-event"), (((GCallback) (motion_notify_event_cb
))), (preview), ((void*)0), (GConnectFlags) 0)
;
530
531 g_signal_connect (G_OBJECT (area), "button-press-event",g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((area)), (((GType) ((20) << (2)))))
)))), ("button-press-event"), (((GCallback) (button_press_event_cb
))), (preview), ((void*)0), (GConnectFlags) 0)
532 G_CALLBACK (button_press_event_cb), preview)g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((area)), (((GType) ((20) << (2)))))
)))), ("button-press-event"), (((GCallback) (button_press_event_cb
))), (preview), ((void*)0), (GConnectFlags) 0)
;
533
534 g_signal_connect (G_OBJECT (area), "button-release-event",g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((area)), (((GType) ((20) << (2)))))
)))), ("button-release-event"), (((GCallback) (button_release_event_cb
))), (preview), ((void*)0), (GConnectFlags) 0)
535 G_CALLBACK (button_release_event_cb), preview)g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((area)), (((GType) ((20) << (2)))))
)))), ("button-release-event"), (((GCallback) (button_release_event_cb
))), (preview), ((void*)0), (GConnectFlags) 0)
;
536
537 g_signal_connect (G_OBJECT (area), "key-press-event",g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((area)), (((GType) ((20) << (2)))))
)))), ("key-press-event"), (((GCallback) (key_press_event_cb)
)), (preview), ((void*)0), (GConnectFlags) 0)
538 G_CALLBACK (key_press_event_cb), preview)g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((area)), (((GType) ((20) << (2)))))
)))), ("key-press-event"), (((GCallback) (key_press_event_cb)
)), (preview), ((void*)0), (GConnectFlags) 0)
;
539
540 g_signal_connect (area, "size-allocate",g_signal_connect_data ((area), ("size-allocate"), (((GCallback
) (size_allocate_cb))), (preview), ((void*)0), (GConnectFlags
) 0)
541 G_CALLBACK (size_allocate_cb), preview)g_signal_connect_data ((area), ("size-allocate"), (((GCallback
) (size_allocate_cb))), (preview), ((void*)0), (GConnectFlags
) 0)
;
542
543 return CTK_WIDGET (preview)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((preview)), ((ctk_widget_get_type ()))))))
;
544}
545
546static gboolean
547draw_cb (CtkDrawingArea *drawing_area,
548 cairo_t *cr,
549 gpointer user_data)
550{
551 update_relative_sizes (EOC_PRINT_PREVIEW (user_data)((((EocPrintPreview*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((user_data)), ((eoc_print_preview_get_type ()))))))
);
552
553 eoc_print_preview_draw (EOC_PRINT_PREVIEW (user_data)((((EocPrintPreview*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((user_data)), ((eoc_print_preview_get_type ()))))))
, cr);
554
555 if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) {
556 fprintf (stderrstderr, "Cairo is unhappy: %s\n",
557 cairo_status_to_string (cairo_status (cr)));
558 }
559
560 return TRUE(!(0));
561}
562
563/**
564 * get_current_image_coordinates:
565 * @preview: an #EocPrintPreview
566 * @x0: A pointer where to store the x coordinate.
567 * @y0: A pointer where to store the y coordinate.
568 *
569 * This function returns the current image coordinates, according
570 * with the properties of the given @preview widget.
571 **/
572static void
573get_current_image_coordinates (EocPrintPreview *preview,
574 gint *x0, gint *y0)
575{
576 EocPrintPreviewPrivate *priv;
577 CtkAllocation allocation;
578
579 priv = preview->priv;
580 ctk_widget_get_allocation (CTK_WIDGET (priv->area)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->area)), ((ctk_widget_get_type ()))))))
, &allocation);
581
582 *x0 = (gint)((1 - priv->image_x_align)*priv->l_rmargin + priv->image_x_align*(allocation.width - priv->r_rmargin - priv->r_width));
583 *y0 = (gint)((1 - priv->image_y_align)*priv->t_rmargin + priv->image_y_align*(allocation.height - priv->b_rmargin - priv->r_height));
584}
585
586/**
587 * press_inside_image_area:
588 * @preview: an #EocPrintPreview
589 * @x: the points x coordinate
590 * @y: the points y coordinate
591 *
592 * Returns whether the given point is inside the image area.
593 *
594 * Returns: %TRUE if the given point is inside of the image area,
595 * %FALSE otherwise.
596 **/
597static gboolean
598press_inside_image_area (EocPrintPreview *preview,
599 guint x,
600 guint y)
601{
602 EocPrintPreviewPrivate *priv;
603 gint x0, y0;
604
605 priv = preview->priv;
606 get_current_image_coordinates (preview, &x0, &y0);
607
608 if (x >= x0 && y >= y0 &&
609 x <= x0 + priv->r_width && y <= y0 + priv->r_height)
610 return TRUE(!(0));
611
612 return FALSE(0);
613}
614
615static void
616create_image_scaled (EocPrintPreview *preview)
617{
618 EocPrintPreviewPrivate *priv = preview->priv;
619
620 if (!priv->image_scaled) {
621 gint i_width, i_height;
622 CtkAllocation allocation;
623
624 ctk_widget_get_allocation (priv->area, &allocation);
625 i_width = gdk_pixbuf_get_width (priv->image);
626 i_height = gdk_pixbuf_get_height (priv->image);
627
628 if ((i_width > allocation.width) ||
629 (i_height > allocation.height)) {
630 gdouble scale;
631 scale = MIN ((gdouble) allocation.width/i_width,((((gdouble) allocation.width/i_width) < ((gdouble) allocation
.height/i_height)) ? ((gdouble) allocation.width/i_width) : (
(gdouble) allocation.height/i_height))
632 (gdouble) allocation.height/i_height)((((gdouble) allocation.width/i_width) < ((gdouble) allocation
.height/i_height)) ? ((gdouble) allocation.width/i_width) : (
(gdouble) allocation.height/i_height))
;
633 scale *= ctk_widget_get_scale_factor (CTK_WIDGET (priv->area)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->area)), ((ctk_widget_get_type ()))))))
);
634 priv->image_scaled = gdk_pixbuf_scale_simple (priv->image,
635 i_width*scale,
636 i_height*scale,
637 GDK_INTERP_TILES);
638 } else {
639 priv->image_scaled = priv->image;
640 g_object_ref (priv->image_scaled)((__typeof__ (priv->image_scaled)) (g_object_ref) (priv->
image_scaled))
;
641 }
642 }
643}
644
645static GdkPixbuf *
646create_preview_buffer (EocPrintPreview *preview)
647{
648 GdkPixbuf *pixbuf;
649 gint width, height, widget_scale;
650 GdkInterpType type = GDK_INTERP_TILES;
651
652 if (preview->priv->image == NULL((void*)0)) {
653 return NULL((void*)0);
654 }
655
656 create_image_scaled (preview);
657
658 width = gdk_pixbuf_get_width (preview->priv->image);
659 height = gdk_pixbuf_get_height (preview->priv->image);
660 widget_scale = ctk_widget_get_scale_factor (CTK_WIDGET (preview->priv->area)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((preview->priv->area)), ((ctk_widget_get_type ())))
)))
);
661
662 width *= preview->priv->i_scale * preview->priv->p_scale
663 * widget_scale;
664 height *= preview->priv->i_scale * preview->priv->p_scale
665 * widget_scale;
666
667 if (width < 1 || height < 1)
668 return NULL((void*)0);
669
670 /* to use GDK_INTERP_TILES for small pixbufs is expensive and unnecessary */
671 if (width < 25 || height < 25)
672 type = GDK_INTERP_NEAREST;
673
674 if (preview->priv->image_scaled) {
675 pixbuf = gdk_pixbuf_scale_simple (preview->priv->image_scaled,
676 width, height, type);
677 } else {
678 pixbuf = gdk_pixbuf_scale_simple (preview->priv->image,
679 width, height, type);
680 }
681
682 return pixbuf;
683}
684
685static void
686create_surface (EocPrintPreview *preview)
687{
688 EocPrintPreviewPrivate *priv = preview->priv;
689 GdkPixbuf *pixbuf;
690
691 if (priv->surface) {
692 cairo_surface_destroy (priv->surface);
693 priv->surface = NULL((void*)0);
694 }
695
696 pixbuf = create_preview_buffer (preview);
697 if (pixbuf) {
698 priv->surface =
699 cdk_cairo_surface_create_from_pixbuf (pixbuf, 0,
700 ctk_widget_get_window (CTK_WIDGET (preview)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((preview)), ((ctk_widget_get_type ()))))))
));
701 g_object_unref (pixbuf);
702 }
703 priv->flag_create_surface = FALSE(0);
704}
705
706static gboolean
707create_surface_when_idle (EocPrintPreview *preview)
708{
709 create_surface (preview);
710
711 return FALSE(0);
712}
713
714static gboolean
715button_press_event_cb (CtkWidget *widget,
716 CdkEventButton *event,
717 gpointer user_data)
718{
719 EocPrintPreview *preview = EOC_PRINT_PREVIEW (user_data)((((EocPrintPreview*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((user_data)), ((eoc_print_preview_get_type ()))))))
;
720
721 preview->priv->cursorx = event->x;
722 preview->priv->cursory = event->y;
723
724 switch (event->button) {
725 case 1:
726 preview->priv->grabbed = press_inside_image_area (preview, event->x, event->y);
727 break;
728 }
729
730 if (preview->priv->grabbed) {
731 ctk_widget_queue_draw (CTK_WIDGET (preview)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((preview)), ((ctk_widget_get_type ()))))))
);
732 }
733
734 ctk_widget_grab_focus (preview->priv->area);
735
736 return FALSE(0);
737}
738
739static gboolean
740button_release_event_cb (CtkWidget *widget,
741 CdkEventButton *event,
742 gpointer user_data)
743{
744 EocPrintPreview *preview = EOC_PRINT_PREVIEW (user_data)((((EocPrintPreview*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((user_data)), ((eoc_print_preview_get_type ()))))))
;
745
746 switch (event->button) {
747 case 1:
748 preview->priv->grabbed = FALSE(0);
749 preview->priv->r_dx = 0;
750 preview->priv->r_dy = 0;
751 ctk_widget_queue_draw (CTK_WIDGET (preview)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((preview)), ((ctk_widget_get_type ()))))))
);
752
753 }
754 return FALSE(0);
755}
756
757static gboolean
758key_press_event_cb (CtkWidget *widget,
759 CdkEventKey *event,
760 gpointer user_data)
761{
762 gfloat delta, align;
763 gboolean stop_emission = FALSE(0);
764 const gchar *property;
1
'property' declared without an initial value
765
766 delta = 0;
767
768 switch (event->keyval) {
769 case CDK_KEY_Left0xff51:
770 property = "image-x-align";
771 delta = -0.01;
772 break;
773 case CDK_KEY_Right0xff53:
774 property = "image-x-align";
775 delta = 0.01;
776 break;
777 case CDK_KEY_Up0xff52:
778 property = "image-y-align";
779 delta = -0.01;
780 break;
781 case CDK_KEY_Down0xff54:
782 property = "image-y-align";
783 delta = 0.01;
784 break;
785 }
786
787 if (delta != 0) {
2
'Default' branch taken. Execution continues on line 787
3
Assuming 'delta' is not equal to 0
4
Taking true branch
788 g_object_get (G_OBJECT (user_data)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((user_data)), (((GType) ((20) << (2))))))))
,
5
2nd function call argument is an uninitialized value
789 property, &align,
790 NULL((void*)0));
791
792 align += delta;
793 align = CLAMP (align, 0, 1)(((align) > (1)) ? (1) : (((align) < (0)) ? (0) : (align
)))
;
794 g_object_set (G_OBJECT (user_data)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((user_data)), (((GType) ((20) << (2))))))))
,
795 property, align,
796 NULL((void*)0));
797
798 stop_emission = TRUE(!(0));
799 g_signal_emit (G_OBJECT (user_data)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((user_data)), (((GType) ((20) << (2))))))))
,
800 preview_signals
801 [SIGNAL_IMAGE_MOVED], 0);
802 }
803
804 return stop_emission;
805}
806
807static gboolean
808motion_notify_event_cb (CtkWidget *widget,
809 CdkEventMotion *event,
810 gpointer user_data)
811{
812 EocPrintPreviewPrivate *priv = EOC_PRINT_PREVIEW (user_data)((((EocPrintPreview*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((user_data)), ((eoc_print_preview_get_type ()))))))
->priv;
813 gdouble dx, dy;
814 CtkAllocation allocation;
815
816 if (priv->grabbed) {
817 dx = event->x - priv->cursorx;
818 dy = event->y - priv->cursory;
819
820 ctk_widget_get_allocation (widget, &allocation);
821
822 /* Make sure the image stays inside the margins */
823
824 priv->image_x_align += (dx + priv->r_dx)/(allocation.width - priv->r_width - priv->l_rmargin - priv->r_rmargin);
825 if (priv->image_x_align < 0. || priv->image_x_align > 1.) {
826 priv->image_x_align = CLAMP (priv->image_x_align, 0., 1.)(((priv->image_x_align) > (1.)) ? (1.) : (((priv->image_x_align
) < (0.)) ? (0.) : (priv->image_x_align)))
;
827 priv->r_dx += dx;
828 }
829 else
830 priv->r_dx = 0;
831
832 priv->image_y_align += (dy + priv->r_dy)/(allocation.height - priv->r_height - priv->t_rmargin - priv->b_rmargin);
833 if (priv->image_y_align < 0. || priv->image_y_align > 1.) {
834 priv->image_y_align = CLAMP (priv->image_y_align, 0., 1.)(((priv->image_y_align) > (1.)) ? (1.) : (((priv->image_y_align
) < (0.)) ? (0.) : (priv->image_y_align)))
;
835 priv->r_dy += dy;
836 } else
837 priv->r_dy = 0;
838
839 /* we do this to correctly change the property values */
840 g_object_set (EOC_PRINT_PREVIEW (user_data)((((EocPrintPreview*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((user_data)), ((eoc_print_preview_get_type ()))))))
,
841 "image-x-align", priv->image_x_align,
842 "image-y-align", priv->image_y_align,
843 NULL((void*)0));
844
845 priv->cursorx = event->x;
846 priv->cursory = event->y;
847
848 g_signal_emit (G_OBJECT (user_data)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((user_data)), (((GType) ((20) << (2))))))))
,
849 preview_signals
850 [SIGNAL_IMAGE_MOVED], 0);
851 } else {
852 if (press_inside_image_area (EOC_PRINT_PREVIEW (user_data)((((EocPrintPreview*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((user_data)), ((eoc_print_preview_get_type ()))))))
, event->x, event->y)) {
853 CdkCursor *cursor;
854 cursor = cdk_cursor_new_for_display (ctk_widget_get_display (widget),
855 CDK_FLEUR);
856 cdk_window_set_cursor (ctk_widget_get_window (widget),
857 cursor);
858 g_object_unref (cursor);
859 } else {
860 cdk_window_set_cursor (ctk_widget_get_window (widget),
861 NULL((void*)0));
862 }
863 }
864 return FALSE(0);
865}
866
867static void
868size_allocate_cb (CtkWidget *widget,
869 CtkAllocation *allocation,
870 gpointer user_data)
871{
872 EocPrintPreview *preview;
873
874 preview = EOC_PRINT_PREVIEW (user_data)((((EocPrintPreview*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((user_data)), ((eoc_print_preview_get_type ()))))))
;
875 update_relative_sizes (preview);
876
877 preview->priv->flag_create_surface = TRUE(!(0));
878
879 if (preview->priv->image_scaled) {
880 g_object_unref (preview->priv->image_scaled);
881 preview->priv->image_scaled = NULL((void*)0);
882 }
883
884 g_idle_add ((GSourceFunc) create_surface_when_idle, preview);
885}
886
887static void
888eoc_print_preview_draw (EocPrintPreview *preview, cairo_t *cr)
889{
890 EocPrintPreviewPrivate *priv;
891 CtkWidget *area;
892 CtkAllocation allocation;
893 gint x0, y0;
894 gboolean has_focus;
895
896 priv = preview->priv;
897 area = priv->area;
898
899 has_focus = ctk_widget_has_focus (area);
900
901 ctk_widget_get_allocation (area, &allocation);
902
903 /* draw the page */
904 cairo_set_source_rgb (cr, 1., 1., 1.);
905 cairo_rectangle (cr, 0, 0, allocation.width, allocation.height);
906 cairo_fill (cr);
907
908 /* draw the page margins */
909 cairo_set_source_rgb (cr, 0., 0., 0.);
910 cairo_set_line_width (cr, 0.1);
911 cairo_rectangle (cr,
912 priv->l_rmargin, priv->t_rmargin,
913 allocation.width - priv->l_rmargin - priv->r_rmargin,
914 allocation.height - priv->t_rmargin - priv->b_rmargin);
915 cairo_stroke (cr);
916
917 get_current_image_coordinates (preview, &x0, &y0);
918
919 if (priv->flag_create_surface) {
920 create_surface (preview);
921 }
922
923 if (priv->surface) {
924 cairo_set_source_surface (cr, priv->surface, x0, y0);
925 cairo_paint (cr);
926 } else if (priv->image_scaled) {
927 /* just in the remote case we don't have the surface */
928
929 /* adjust (x0, y0) to the new scale */
930 gdouble scale = priv->i_scale * priv->p_scale *
931 gdk_pixbuf_get_width (priv->image) / gdk_pixbuf_get_width (priv->image_scaled);
932 x0 /= scale;
933 y0 /= scale;
934
935 cairo_scale (cr, scale, scale);
936 cdk_cairo_set_source_pixbuf (cr, priv->image_scaled, x0, y0);
937 cairo_paint (cr);
938 } else if (priv->image) {
939 /* just in the remote case we don't have the surface */
940
941 /* adjust (x0, y0) to the new scale */
942 x0 /= priv->i_scale * priv->p_scale;
943 y0 /= priv->i_scale * priv->p_scale;
944
945 cairo_scale (cr, priv->i_scale*priv->p_scale, priv->i_scale*priv->p_scale);
946 cdk_cairo_set_source_pixbuf (cr, priv->image, x0, y0);
947 cairo_paint (cr);
948 }
949
950 if (has_focus) {
951 CtkStyleContext *ctx;
952
953 ctx = ctk_widget_get_style_context (area);
954 ctk_render_focus (ctx, cr, 0, 0,
955 allocation.width, allocation.height);
956 }
957}
958
959static void
960update_relative_sizes (EocPrintPreview *preview)
961{
962 EocPrintPreviewPrivate *priv;
963 CtkAllocation allocation;
964 gint i_width, i_height;
965
966 priv = preview->priv;
967
968 if (priv->image != NULL((void*)0)) {
969 i_width = gdk_pixbuf_get_width (priv->image);
970 i_height = gdk_pixbuf_get_height (priv->image);
971 } else {
972 i_width = i_height = 0;
973 }
974
975 ctk_widget_get_allocation (priv->area, &allocation);
976
977 priv->p_scale = (gfloat) allocation.width / (priv->p_width * 72.0);
978
979 priv->r_width = (gint) i_width * priv->i_scale * priv->p_scale;
980 priv->r_height = (gint) i_height * priv->i_scale * priv->p_scale;
981
982 priv->l_rmargin = (gint) (72. * priv->l_margin * priv->p_scale);
983 priv->r_rmargin = (gint) (72. * priv->r_margin * priv->p_scale);
984 priv->t_rmargin = (gint) (72. * priv->t_margin * priv->p_scale);
985 priv->b_rmargin = (gint) (72. * priv->b_margin * priv->p_scale);
986}
987
988/**
989 * eoc_print_preview_set_page_margins:
990 * @preview: a #EocPrintPreview
991 * @l_margin: Left margin.
992 * @r_margin: Right margin.
993 * @t_margin: Top margin.
994 * @b_margin: Bottom margin.
995 *
996 * Manually set the margins, in inches.
997 **/
998void
999eoc_print_preview_set_page_margins (EocPrintPreview *preview,
1000 gfloat l_margin,
1001 gfloat r_margin,
1002 gfloat t_margin,
1003 gfloat b_margin)
1004{
1005 g_return_if_fail (EOC_IS_PRINT_PREVIEW (preview))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((preview)); GType __t = ((eoc_print_preview_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 ("EOC", ((const char
*) (__func__)), "EOC_IS_PRINT_PREVIEW (preview)"); return; } }
while (0)
;
1006
1007 g_object_set (G_OBJECT(preview)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((preview)), (((GType) ((20) << (2))))))))
,
1008 "page-left-margin", l_margin,
1009 "page-right-margin", r_margin,
1010 "page-top-margin", t_margin,
1011 "page-bottom-margin", r_margin,
1012 NULL((void*)0));
1013}
1014
1015/**
1016 * eoc_print_preview_set_from_page_setup:
1017 * @preview: a #EocPrintPreview
1018 * @setup: a #CtkPageSetup to set the properties from
1019 *
1020 * Sets up the page properties from a #CtkPageSetup. Useful when using the
1021 * widget with the CtkPrint API.
1022 **/
1023void
1024eoc_print_preview_set_from_page_setup (EocPrintPreview *preview,
1025 CtkPageSetup *setup)
1026{
1027 g_return_if_fail (EOC_IS_PRINT_PREVIEW (preview))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((preview)); GType __t = ((eoc_print_preview_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 ("EOC", ((const char
*) (__func__)), "EOC_IS_PRINT_PREVIEW (preview)"); return; } }
while (0)
;
1028 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 ("EOC", ((const char*) (__func__
)), "CTK_IS_PAGE_SETUP (setup)"); return; } } while (0)
;
1029
1030 g_object_set (G_OBJECT (preview)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((preview)), (((GType) ((20) << (2))))))))
,
1031 "page-left-margin", ctk_page_setup_get_left_margin (setup, CTK_UNIT_INCH),
1032 "page-right-margin", ctk_page_setup_get_right_margin (setup, CTK_UNIT_INCH),
1033 "page-top-margin", ctk_page_setup_get_top_margin (setup, CTK_UNIT_INCH),
1034 "page-bottom-margin", ctk_page_setup_get_bottom_margin (setup, CTK_UNIT_INCH),
1035 "paper-width", ctk_page_setup_get_paper_width (setup, CTK_UNIT_INCH),
1036 "paper-height", ctk_page_setup_get_paper_height (setup, CTK_UNIT_INCH),
1037 NULL((void*)0));
1038
1039}
1040
1041/**
1042 * eoc_print_preview_get_image_position:
1043 * @preview: a #EocPrintPreview
1044 * @x: a pointer to a #gdouble, or %NULL to ignore it
1045 * @y: a pointer to a #gdouble, or %NULL to ignore it
1046 *
1047 * Gets current image position in inches, relative to the margins. A
1048 * (0, 0) position is the intersection between the left and top margins.
1049 **/
1050void
1051eoc_print_preview_get_image_position (EocPrintPreview *preview,
1052 gdouble *x,
1053 gdouble *y)
1054{
1055 EocPrintPreviewPrivate *priv;
1056 gdouble width, height;
1057
1058 g_return_if_fail (EOC_IS_PRINT_PREVIEW (preview))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((preview)); GType __t = ((eoc_print_preview_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 ("EOC", ((const char
*) (__func__)), "EOC_IS_PRINT_PREVIEW (preview)"); return; } }
while (0)
;
1059
1060 priv = preview->priv;
1061
1062 if (x != NULL((void*)0)) {
1063 width = gdk_pixbuf_get_width (priv->image) * priv->i_scale / 72.;
1064 *x = priv->image_x_align * (priv->p_width - priv->l_margin - priv->r_margin - width);
1065 }
1066 if (y != NULL((void*)0)) {
1067 height = gdk_pixbuf_get_height (priv->image) * priv->i_scale / 72.;
1068 *y = priv->image_y_align * (priv->p_height - priv->t_margin - priv->b_margin - height);
1069 }
1070}
1071
1072/**
1073 * eoc_print_preview_set_image_position:
1074 * @preview: a #EocPrintPreview
1075 * @x: The X coordinate, in inches, or -1 to ignore it.
1076 * @y: The Y coordinate, in inches, or -1 to ignore it.
1077 *
1078 * Sets the image position. You can pass -1 to one of the coordinates if you
1079 * only want to set the other.
1080 **/
1081void
1082eoc_print_preview_set_image_position (EocPrintPreview *preview,
1083 gdouble x,
1084 gdouble y)
1085{
1086 EocPrintPreviewPrivate *priv;
1087 gfloat x_align, y_align;
1088 gdouble width, height;
1089
1090 g_return_if_fail (EOC_IS_PRINT_PREVIEW (preview))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((preview)); GType __t = ((eoc_print_preview_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 ("EOC", ((const char
*) (__func__)), "EOC_IS_PRINT_PREVIEW (preview)"); return; } }
while (0)
;
1091
1092 priv = preview->priv;
1093
1094 if (x != -1) {
1095 width = gdk_pixbuf_get_width (priv->image) * priv->i_scale / 72.;
1096 x_align = CLAMP (x/(priv->p_width - priv->l_margin - priv->r_margin - width), 0, 1)(((x/(priv->p_width - priv->l_margin - priv->r_margin
- width)) > (1)) ? (1) : (((x/(priv->p_width - priv->
l_margin - priv->r_margin - width)) < (0)) ? (0) : (x/(
priv->p_width - priv->l_margin - priv->r_margin - width
))))
;
1097 g_object_set (preview, "image-x-align", x_align, NULL((void*)0));
1098 }
1099
1100 if (y != -1) {
1101 height = gdk_pixbuf_get_height (priv->image) * priv->i_scale / 72.;
1102 y_align = CLAMP (y/(priv->p_height - priv->t_margin - priv->b_margin - height), 0, 1)(((y/(priv->p_height - priv->t_margin - priv->b_margin
- height)) > (1)) ? (1) : (((y/(priv->p_height - priv->
t_margin - priv->b_margin - height)) < (0)) ? (0) : (y/
(priv->p_height - priv->t_margin - priv->b_margin - height
))))
;
1103 g_object_set (preview, "image-y-align", y_align, NULL((void*)0));
1104 }
1105}
1106
1107/**
1108 * eoc_print_preview_set_scale:
1109 * @preview: a #EocPrintPreview
1110 * @scale: a scale value, between 0 and 1.
1111 *
1112 * Sets the scale for the image.
1113 **/
1114void
1115eoc_print_preview_set_scale (EocPrintPreview *preview,
1116 gfloat scale)
1117{
1118 g_return_if_fail (EOC_IS_PRINT_PREVIEW (preview))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((preview)); GType __t = ((eoc_print_preview_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 ("EOC", ((const char
*) (__func__)), "EOC_IS_PRINT_PREVIEW (preview)"); return; } }
while (0)
;
1119
1120 g_object_set (preview,
1121 "image-scale", scale,
1122 NULL((void*)0));
1123}