File: | ctk/ctkpapersize.c |
Warning: | line 284, column 7 Out of bound memory access (access exceeds upper limit of memory block) |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* CTK - The GIMP Toolkit | |||
2 | * ctkpapersize.c: Paper Size | |||
3 | * Copyright (C) 2006, Red Hat, Inc. | |||
4 | * Copyright © 2006, 2007 Christian Persch | |||
5 | * | |||
6 | * This library is free software; you can redistribute it and/or | |||
7 | * modify it under the terms of the GNU Lesser General Public | |||
8 | * License as published by the Free Software Foundation; either | |||
9 | * version 2 of the License, or (at your option) any later version. | |||
10 | * | |||
11 | * This library is distributed in the hope that it will be useful, | |||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
14 | * Lesser General Public License for more details. | |||
15 | * | |||
16 | * You should have received a copy of the GNU Lesser General Public | |||
17 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. | |||
18 | */ | |||
19 | ||||
20 | #include "config.h" | |||
21 | #include <string.h> | |||
22 | #include <stdlib.h> | |||
23 | #include <locale.h> | |||
24 | #if defined(HAVE__NL_PAPER_HEIGHT1) && defined(HAVE__NL_PAPER_WIDTH1) | |||
25 | #include <langinfo.h> | |||
26 | #endif | |||
27 | #include <math.h> | |||
28 | ||||
29 | #include "ctkpapersize.h" | |||
30 | #include "ctkprintutils.h" | |||
31 | #include "ctkprintoperation.h" /* for CtkPrintError */ | |||
32 | #include "ctkintl.h" | |||
33 | ||||
34 | /* _ctk_load_custom_papers() only on Unix so far */ | |||
35 | #ifdef G_OS_UNIX | |||
36 | #include "ctkcustompaperunixdialog.h" | |||
37 | #endif | |||
38 | ||||
39 | #include "paper_names_offsets.c" | |||
40 | ||||
41 | ||||
42 | /** | |||
43 | * SECTION:ctkpapersize | |||
44 | * @Short_description: Support for named paper sizes | |||
45 | * @Title: CtkPaperSize | |||
46 | * @See_also:#CtkPageSetup | |||
47 | * | |||
48 | * CtkPaperSize handles paper sizes. It uses the standard called | |||
49 | * [PWG 5101.1-2002 PWG: Standard for Media Standardized Names](http://www.pwg.org/standards.html) | |||
50 | * to name the paper sizes (and to get the data for the page sizes). | |||
51 | * In addition to standard paper sizes, CtkPaperSize allows to | |||
52 | * construct custom paper sizes with arbitrary dimensions. | |||
53 | * | |||
54 | * The #CtkPaperSize object stores not only the dimensions (width | |||
55 | * and height) of a paper size and its name, it also provides | |||
56 | * default [print margins][print-margins]. | |||
57 | * | |||
58 | * Printing support has been added in CTK+ 2.10. | |||
59 | */ | |||
60 | ||||
61 | ||||
62 | struct _CtkPaperSize | |||
63 | { | |||
64 | const PaperInfo *info; | |||
65 | ||||
66 | /* If these are not set we fall back to info */ | |||
67 | gchar *name; | |||
68 | gchar *display_name; | |||
69 | gchar *ppd_name; | |||
70 | ||||
71 | gdouble width, height; /* Stored in mm */ | |||
72 | gboolean is_custom; | |||
73 | gboolean is_ipp; | |||
74 | }; | |||
75 | ||||
76 | G_DEFINE_BOXED_TYPE (CtkPaperSize, ctk_paper_size,static GType ctk_paper_size_get_type_once (void); GType ctk_paper_size_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_paper_size_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_paper_size_get_type_once (void ) { GType (* _g_register_boxed) (const gchar *, union { CtkPaperSize * (*do_copy_type) (CtkPaperSize *); CtkPaperSize * (*do_const_copy_type ) (const CtkPaperSize *); GBoxedCopyFunc do_copy_boxed; } __attribute__ ((__transparent_union__)), union { void (* do_free_type) (CtkPaperSize *); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__ )) ) = g_boxed_type_register_static; GType g_define_type_id = _g_register_boxed (g_intern_static_string ("CtkPaperSize"), ctk_paper_size_copy , ctk_paper_size_free); { {{};} } return g_define_type_id; } | |||
77 | ctk_paper_size_copy,static GType ctk_paper_size_get_type_once (void); GType ctk_paper_size_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_paper_size_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_paper_size_get_type_once (void ) { GType (* _g_register_boxed) (const gchar *, union { CtkPaperSize * (*do_copy_type) (CtkPaperSize *); CtkPaperSize * (*do_const_copy_type ) (const CtkPaperSize *); GBoxedCopyFunc do_copy_boxed; } __attribute__ ((__transparent_union__)), union { void (* do_free_type) (CtkPaperSize *); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__ )) ) = g_boxed_type_register_static; GType g_define_type_id = _g_register_boxed (g_intern_static_string ("CtkPaperSize"), ctk_paper_size_copy , ctk_paper_size_free); { {{};} } return g_define_type_id; } | |||
78 | ctk_paper_size_free)static GType ctk_paper_size_get_type_once (void); GType ctk_paper_size_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_paper_size_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_paper_size_get_type_once (void ) { GType (* _g_register_boxed) (const gchar *, union { CtkPaperSize * (*do_copy_type) (CtkPaperSize *); CtkPaperSize * (*do_const_copy_type ) (const CtkPaperSize *); GBoxedCopyFunc do_copy_boxed; } __attribute__ ((__transparent_union__)), union { void (* do_free_type) (CtkPaperSize *); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__ )) ) = g_boxed_type_register_static; GType g_define_type_id = _g_register_boxed (g_intern_static_string ("CtkPaperSize"), ctk_paper_size_copy , ctk_paper_size_free); { {{};} } return g_define_type_id; } | |||
79 | ||||
80 | static const PaperInfo * | |||
81 | lookup_paper_info (const gchar *name) | |||
82 | { | |||
83 | int lower = 0; | |||
84 | int upper = G_N_ELEMENTS (standard_names_offsets)(sizeof (standard_names_offsets) / sizeof ((standard_names_offsets )[0])) - 1; | |||
85 | ||||
86 | do | |||
87 | { | |||
88 | int mid; | |||
89 | int cmp; | |||
90 | ||||
91 | mid = (lower + upper) / 2; | |||
92 | cmp = strcmp (name, paper_names + standard_names_offsets[mid].name); | |||
93 | if (cmp < 0) | |||
94 | upper = mid - 1; | |||
95 | else if (cmp > 0) | |||
96 | lower = mid + 1; | |||
97 | else | |||
98 | return &standard_names_offsets[mid]; | |||
99 | } | |||
100 | while (lower <= upper); | |||
101 | ||||
102 | return NULL((void*)0); | |||
103 | } | |||
104 | ||||
105 | static gboolean | |||
106 | parse_media_size (const gchar *size, | |||
107 | gdouble *width_mm, | |||
108 | gdouble *height_mm) | |||
109 | { | |||
110 | const char *p; | |||
111 | char *e; | |||
112 | double short_dim, long_dim; | |||
113 | ||||
114 | p = size; | |||
115 | ||||
116 | short_dim = g_ascii_strtod (p, &e); | |||
117 | ||||
118 | if (p == e || *e != 'x') | |||
119 | return FALSE(0); | |||
120 | ||||
121 | p = e + 1; /* Skip x */ | |||
122 | ||||
123 | long_dim = g_ascii_strtod (p, &e); | |||
124 | ||||
125 | if (p == e) | |||
126 | return FALSE(0); | |||
127 | ||||
128 | p = e; | |||
129 | ||||
130 | if (strcmp (p, "in") == 0) | |||
131 | { | |||
132 | short_dim = short_dim * MM_PER_INCH25.4; | |||
133 | long_dim = long_dim * MM_PER_INCH25.4; | |||
134 | } | |||
135 | else if (strcmp (p, "mm") != 0) | |||
136 | return FALSE(0); | |||
137 | ||||
138 | if (width_mm) | |||
139 | *width_mm = short_dim; | |||
140 | if (height_mm) | |||
141 | *height_mm = long_dim; | |||
142 | ||||
143 | return TRUE(!(0)); | |||
144 | } | |||
145 | ||||
146 | static gboolean | |||
147 | parse_full_media_size_name (const gchar *full_name, | |||
148 | gchar **name, | |||
149 | gdouble *width_mm, | |||
150 | gdouble *height_mm) | |||
151 | { | |||
152 | const char *p; | |||
153 | const char *end_of_name; | |||
154 | ||||
155 | /* From the spec: | |||
156 | media-size-self-describing-name = | |||
157 | ( class-in "_" size-name "_" short-dim "x" long-dim "in" ) | | |||
158 | ( class-mm "_" size-name "_" short-dim "x" long-dim "mm" ) | |||
159 | class-in = "custom" | "na" | "asme" | "roc" | "oe" | |||
160 | class-mm = "custom" | "iso" | "jis" | "jpn" | "prc" | "om" | |||
161 | size-name = ( lowalpha | digit ) *( lowalpha | digit | "-" ) | |||
162 | short-dim = dim | |||
163 | long-dim = dim | |||
164 | dim = integer-part [fraction-part] | "0" fraction-part | |||
165 | integer-part = non-zero-digit *digit | |||
166 | fraction-part = "." *digit non-zero-digit | |||
167 | lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | | |||
168 | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | | |||
169 | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" | |||
170 | non-zero-digit = "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | |||
171 | digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | |||
172 | */ | |||
173 | ||||
174 | p = strchr (full_name, '_'); | |||
175 | if (p == NULL((void*)0)) | |||
176 | return FALSE(0); | |||
177 | ||||
178 | p++; /* Skip _ */ | |||
179 | ||||
180 | p = strchr (p, '_'); | |||
181 | if (p == NULL((void*)0)) | |||
182 | return FALSE(0); | |||
183 | ||||
184 | end_of_name = p; | |||
185 | ||||
186 | p++; /* Skip _ */ | |||
187 | ||||
188 | if (!parse_media_size (p, width_mm, height_mm)) | |||
189 | return FALSE(0); | |||
190 | ||||
191 | if (name) | |||
192 | *name = g_strndup (full_name, end_of_name - full_name); | |||
193 | ||||
194 | return TRUE(!(0)); | |||
195 | } | |||
196 | ||||
197 | static CtkPaperSize * | |||
198 | ctk_paper_size_new_from_info (const PaperInfo *info) | |||
199 | { | |||
200 | CtkPaperSize *size; | |||
201 | ||||
202 | size = g_slice_new0 (CtkPaperSize)((CtkPaperSize*) g_slice_alloc0 (sizeof (CtkPaperSize))); | |||
203 | size->info = info; | |||
204 | size->width = info->width; | |||
205 | size->height = info->height; | |||
206 | ||||
207 | return size; | |||
208 | } | |||
209 | ||||
210 | /** | |||
211 | * ctk_paper_size_new: | |||
212 | * @name: (allow-none): a paper size name, or %NULL | |||
213 | * | |||
214 | * Creates a new #CtkPaperSize object by parsing a | |||
215 | * [PWG 5101.1-2002](ftp://ftp.pwg.org/pub/pwg/candidates/cs-pwgmsn10-20020226-5101.1.pdf) | |||
216 | * paper name. | |||
217 | * | |||
218 | * If @name is %NULL, the default paper size is returned, | |||
219 | * see ctk_paper_size_get_default(). | |||
220 | * | |||
221 | * Returns: a new #CtkPaperSize, use ctk_paper_size_free() | |||
222 | * to free it | |||
223 | * | |||
224 | * Since: 2.10 | |||
225 | */ | |||
226 | CtkPaperSize * | |||
227 | ctk_paper_size_new (const gchar *name) | |||
228 | { | |||
229 | CtkPaperSize *size; | |||
230 | char *short_name; | |||
231 | double width, height; | |||
232 | const PaperInfo *info; | |||
233 | ||||
234 | if (name == NULL((void*)0)) | |||
235 | name = ctk_paper_size_get_default (); | |||
236 | ||||
237 | if (parse_full_media_size_name (name, &short_name, &width, &height)) | |||
238 | { | |||
239 | info = lookup_paper_info (short_name); | |||
240 | if (info != NULL((void*)0) && info->width == width && info->height == height) | |||
241 | { | |||
242 | size = ctk_paper_size_new_from_info (info); | |||
243 | g_free (short_name); | |||
244 | } | |||
245 | else | |||
246 | { | |||
247 | size = g_slice_new0 (CtkPaperSize)((CtkPaperSize*) g_slice_alloc0 (sizeof (CtkPaperSize))); | |||
248 | ||||
249 | size->width = width; | |||
250 | size->height = height; | |||
251 | size->name = short_name; | |||
252 | size->display_name = g_strdup (short_name)g_strdup_inline (short_name); | |||
253 | if (strncmp (short_name, "custom", 6) == 0) | |||
254 | size->is_custom = TRUE(!(0)); | |||
255 | } | |||
256 | } | |||
257 | else | |||
258 | { | |||
259 | info = lookup_paper_info (name); | |||
260 | if (info != NULL((void*)0)) | |||
261 | size = ctk_paper_size_new_from_info (info); | |||
262 | else | |||
263 | { | |||
264 | g_warning ("Unknown paper size %s", name); | |||
265 | size = g_slice_new0 (CtkPaperSize)((CtkPaperSize*) g_slice_alloc0 (sizeof (CtkPaperSize))); | |||
266 | size->name = g_strdup (name)g_strdup_inline (name); | |||
267 | size->display_name = g_strdup (name)g_strdup_inline (name); | |||
268 | /* Default to A4 size */ | |||
269 | size->width = 210; | |||
270 | size->height = 297; | |||
271 | } | |||
272 | } | |||
273 | ||||
274 | return size; | |||
275 | } | |||
276 | ||||
277 | static gchar * | |||
278 | improve_displayname (const gchar *name) | |||
279 | { | |||
280 | gchar *p, *s; | |||
281 | ||||
282 | p = strrchr (name, 'x'); | |||
283 | if (p && p != name && | |||
| ||||
284 | g_ascii_isdigit (*(p - 1))((g_ascii_table[(guchar) (*(p - 1))] & G_ASCII_DIGIT) != 0 ) && | |||
| ||||
285 | g_ascii_isdigit (*(p + 1))((g_ascii_table[(guchar) (*(p + 1))] & G_ASCII_DIGIT) != 0 )) | |||
286 | { | |||
287 | gchar *p1, *p2; | |||
288 | p1 = g_strndup (name, p - name); | |||
289 | p2 = g_strdup (p + 1)g_strdup_inline (p + 1); | |||
290 | s = g_strconcat (p1, "×", p2, NULL((void*)0)); | |||
291 | g_free (p1); | |||
292 | g_free (p2); | |||
293 | } | |||
294 | else | |||
295 | s = g_strdup (name)g_strdup_inline (name); | |||
296 | ||||
297 | return s; | |||
298 | } | |||
299 | ||||
300 | /** | |||
301 | * ctk_paper_size_new_from_ppd: | |||
302 | * @ppd_name: a PPD paper name | |||
303 | * @ppd_display_name: the corresponding human-readable name | |||
304 | * @width: the paper width, in points | |||
305 | * @height: the paper height in points | |||
306 | * | |||
307 | * Creates a new #CtkPaperSize object by using | |||
308 | * PPD information. | |||
309 | * | |||
310 | * If @ppd_name is not a recognized PPD paper name, | |||
311 | * @ppd_display_name, @width and @height are used to | |||
312 | * construct a custom #CtkPaperSize object. | |||
313 | * | |||
314 | * Returns: a new #CtkPaperSize, use ctk_paper_size_free() | |||
315 | * to free it | |||
316 | * | |||
317 | * Since: 2.10 | |||
318 | */ | |||
319 | CtkPaperSize * | |||
320 | ctk_paper_size_new_from_ppd (const gchar *ppd_name, | |||
321 | const gchar *ppd_display_name, | |||
322 | gdouble width, | |||
323 | gdouble height) | |||
324 | { | |||
325 | char *name; | |||
326 | const char *lookup_ppd_name; | |||
327 | char *freeme; | |||
328 | CtkPaperSize *size; | |||
329 | int i; | |||
330 | char *display_name; | |||
331 | ||||
332 | lookup_ppd_name = ppd_name; | |||
333 | ||||
334 | freeme = NULL((void*)0); | |||
335 | /* Strip out Traverse suffix in matching. */ | |||
336 | if (g_str_has_suffix (ppd_name, ".Transverse")(__builtin_constant_p (".Transverse")? __extension__ ({ const char * const __str = (ppd_name); const char * const __suffix = (".Transverse"); gboolean __result = (0); if (__str == ((void *)0) || __suffix == ((void*)0)) __result = (g_str_has_suffix) (__str, __suffix); else { const size_t __str_len = strlen (( (__str) + !(__str))); const size_t __suffix_len = strlen (((__suffix ) + !(__suffix))); if (__str_len >= __suffix_len) __result = memcmp (__str + __str_len - __suffix_len, ((__suffix) + !( __suffix)), __suffix_len) == 0; } __result; }) : (g_str_has_suffix ) (ppd_name, ".Transverse") )) | |||
337 | { | |||
338 | lookup_ppd_name = freeme = | |||
339 | g_strndup (ppd_name, strlen (ppd_name) - strlen (".Transverse")); | |||
340 | } | |||
341 | ||||
342 | for (i = 0; i < G_N_ELEMENTS (standard_names_offsets)(sizeof (standard_names_offsets) / sizeof ((standard_names_offsets )[0])); i++) | |||
343 | { | |||
344 | if (standard_names_offsets[i].ppd_name != -1 && | |||
345 | strcmp (paper_names + standard_names_offsets[i].ppd_name, lookup_ppd_name) == 0) | |||
346 | { | |||
347 | size = ctk_paper_size_new_from_info (&standard_names_offsets[i]); | |||
348 | goto out; | |||
349 | } | |||
350 | } | |||
351 | ||||
352 | for (i = 0; i < G_N_ELEMENTS (extra_ppd_names_offsets)(sizeof (extra_ppd_names_offsets) / sizeof ((extra_ppd_names_offsets )[0])); i++) | |||
353 | { | |||
354 | if (strcmp (paper_names + extra_ppd_names_offsets[i].ppd_name, lookup_ppd_name) == 0) | |||
355 | { | |||
356 | size = ctk_paper_size_new (paper_names + extra_ppd_names_offsets[i].standard_name); | |||
357 | goto out; | |||
358 | } | |||
359 | } | |||
360 | ||||
361 | name = g_strconcat ("ppd_", ppd_name, NULL((void*)0)); | |||
362 | display_name = improve_displayname (ppd_display_name); | |||
363 | size = ctk_paper_size_new_custom (name, display_name, width, height, CTK_UNIT_POINTS); | |||
364 | g_free (display_name); | |||
365 | g_free (name); | |||
366 | ||||
367 | out: | |||
368 | ||||
369 | if (size->info == NULL((void*)0) || | |||
370 | size->info->ppd_name == -1 || | |||
371 | strcmp (paper_names + size->info->ppd_name, ppd_name) != 0) | |||
372 | size->ppd_name = g_strdup (ppd_name)g_strdup_inline (ppd_name); | |||
373 | ||||
374 | g_free (freeme); | |||
375 | ||||
376 | return size; | |||
377 | } | |||
378 | ||||
379 | /* Tolerance of paper size in points according to PostScript Language Reference */ | |||
380 | #define PAPER_SIZE_TOLERANCE5 5 | |||
381 | ||||
382 | /** | |||
383 | * ctk_paper_size_new_from_ipp: | |||
384 | * @ipp_name: an IPP paper name | |||
385 | * @width: the paper width, in points | |||
386 | * @height: the paper height in points | |||
387 | * | |||
388 | * Creates a new #CtkPaperSize object by using | |||
389 | * IPP information. | |||
390 | * | |||
391 | * If @ipp_name is not a recognized paper name, | |||
392 | * @width and @height are used to | |||
393 | * construct a custom #CtkPaperSize object. | |||
394 | * | |||
395 | * Returns: a new #CtkPaperSize, use ctk_paper_size_free() | |||
396 | * to free it | |||
397 | * | |||
398 | * Since: 3.16 | |||
399 | */ | |||
400 | CtkPaperSize * | |||
401 | ctk_paper_size_new_from_ipp (const gchar *ipp_name, | |||
402 | gdouble width, | |||
403 | gdouble height) | |||
404 | { | |||
405 | CtkPaperSize *size; | |||
406 | const gchar *name = NULL((void*)0); | |||
407 | gboolean found = FALSE(0); | |||
408 | gchar *display_name = NULL((void*)0); | |||
409 | gint i; | |||
410 | ||||
411 | /* Find paper size according to its name */ | |||
412 | for (i = 0; i < G_N_ELEMENTS (standard_names_offsets)(sizeof (standard_names_offsets) / sizeof ((standard_names_offsets )[0])); i++) | |||
413 | { | |||
414 | if (standard_names_offsets[i].name != -1) | |||
415 | name = paper_names + standard_names_offsets[i].name; | |||
416 | if (name != NULL((void*)0) && | |||
417 | /* Given paper size name is equal to a name | |||
418 | from the standard paper size names list. */ | |||
419 | ((g_strcmp0 (ipp_name, name) == 0) || | |||
420 | /* Given paper size name is prefixed by a name | |||
421 | from the standard paper size names list + | |||
422 | it consists of size in its name (e.g. iso_a4_210x297mm). */ | |||
423 | (g_str_has_prefix (ipp_name, name)(__builtin_constant_p (name)? __extension__ ({ const char * const __str = (ipp_name); const char * const __prefix = (name); gboolean __result = (0); if (__str == ((void*)0) || __prefix == ((void *)0)) __result = (g_str_has_prefix) (__str, __prefix); else { const size_t __str_len = strlen (((__str) + !(__str))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix))); if (__str_len >= __prefix_len) __result = memcmp (((__str) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0; } __result; }) : (g_str_has_prefix) (ipp_name, name) ) && | |||
424 | strlen (ipp_name) > strlen (name) + 2 && | |||
425 | ipp_name[strlen (ipp_name)] == '_' && | |||
426 | g_ascii_isdigit (ipp_name[strlen (ipp_name) + 1])((g_ascii_table[(guchar) (ipp_name[strlen (ipp_name) + 1])] & G_ASCII_DIGIT) != 0) && | |||
427 | (g_str_has_suffix (ipp_name, "mm")(__builtin_constant_p ("mm")? __extension__ ({ const char * const __str = (ipp_name); const char * const __suffix = ("mm"); gboolean __result = (0); if (__str == ((void*)0) || __suffix == ((void *)0)) __result = (g_str_has_suffix) (__str, __suffix); else { const size_t __str_len = strlen (((__str) + !(__str))); const size_t __suffix_len = strlen (((__suffix) + !(__suffix))); if (__str_len >= __suffix_len) __result = memcmp (__str + __str_len - __suffix_len, ((__suffix) + !(__suffix)), __suffix_len) == 0; } __result; }) : (g_str_has_suffix) (ipp_name, "mm") ) || | |||
428 | g_str_has_suffix (ipp_name, "in")(__builtin_constant_p ("in")? __extension__ ({ const char * const __str = (ipp_name); const char * const __suffix = ("in"); gboolean __result = (0); if (__str == ((void*)0) || __suffix == ((void *)0)) __result = (g_str_has_suffix) (__str, __suffix); else { const size_t __str_len = strlen (((__str) + !(__str))); const size_t __suffix_len = strlen (((__suffix) + !(__suffix))); if (__str_len >= __suffix_len) __result = memcmp (__str + __str_len - __suffix_len, ((__suffix) + !(__suffix)), __suffix_len) == 0; } __result; }) : (g_str_has_suffix) (ipp_name, "in") ))))) | |||
429 | { | |||
430 | display_name = g_strdup (g_dpgettext2 (GETTEXT_PACKAGE,g_strdup_inline (g_dpgettext2 ("ctk30", "paper size", paper_names + standard_names_offsets[i].display_name)) | |||
431 | "paper size",g_strdup_inline (g_dpgettext2 ("ctk30", "paper size", paper_names + standard_names_offsets[i].display_name)) | |||
432 | paper_names + standard_names_offsets[i].display_name))g_strdup_inline (g_dpgettext2 ("ctk30", "paper size", paper_names + standard_names_offsets[i].display_name)); | |||
433 | found = TRUE(!(0)); | |||
434 | break; | |||
435 | } | |||
436 | } | |||
437 | ||||
438 | /* Find paper size according to its size */ | |||
439 | if (display_name == NULL((void*)0)) | |||
440 | { | |||
441 | for (i = 0; i < G_N_ELEMENTS (standard_names_offsets)(sizeof (standard_names_offsets) / sizeof ((standard_names_offsets )[0])); i++) | |||
442 | { | |||
443 | float x_dimension; | |||
444 | float y_dimension; | |||
445 | ||||
446 | x_dimension = _ctk_print_convert_from_mm (standard_names_offsets[i].width, CTK_UNIT_POINTS); | |||
447 | y_dimension = _ctk_print_convert_from_mm (standard_names_offsets[i].height, CTK_UNIT_POINTS); | |||
448 | ||||
449 | if (fabs (x_dimension - width) <= PAPER_SIZE_TOLERANCE5 && | |||
450 | fabs (y_dimension - height) <= PAPER_SIZE_TOLERANCE5) | |||
451 | { | |||
452 | display_name = g_strdup (g_dpgettext2 (GETTEXT_PACKAGE,g_strdup_inline (g_dpgettext2 ("ctk30", "paper size", paper_names + standard_names_offsets[i].display_name)) | |||
453 | "paper size",g_strdup_inline (g_dpgettext2 ("ctk30", "paper size", paper_names + standard_names_offsets[i].display_name)) | |||
454 | paper_names + standard_names_offsets[i].display_name))g_strdup_inline (g_dpgettext2 ("ctk30", "paper size", paper_names + standard_names_offsets[i].display_name)); | |||
455 | found = TRUE(!(0)); | |||
456 | break; | |||
457 | } | |||
458 | } | |||
459 | } | |||
460 | ||||
461 | /* Fallback to name of the paper size as given in "ipp_name" parameter */ | |||
462 | if (display_name == NULL((void*)0)) | |||
463 | display_name = g_strdup (ipp_name)g_strdup_inline (ipp_name); | |||
464 | ||||
465 | size = ctk_paper_size_new_custom (ipp_name, display_name, width, height, CTK_UNIT_POINTS); | |||
466 | size->is_custom = !found; | |||
467 | size->is_ipp = found; | |||
468 | ||||
469 | g_free (display_name); | |||
470 | ||||
471 | return size; | |||
472 | } | |||
473 | ||||
474 | /** | |||
475 | * ctk_paper_size_new_custom: | |||
476 | * @name: the paper name | |||
477 | * @display_name: the human-readable name | |||
478 | * @width: the paper width, in units of @unit | |||
479 | * @height: the paper height, in units of @unit | |||
480 | * @unit: the unit for @width and @height. not %CTK_UNIT_NONE. | |||
481 | * | |||
482 | * Creates a new #CtkPaperSize object with the | |||
483 | * given parameters. | |||
484 | * | |||
485 | * Returns: a new #CtkPaperSize object, use ctk_paper_size_free() | |||
486 | * to free it | |||
487 | * | |||
488 | * Since: 2.10 | |||
489 | */ | |||
490 | CtkPaperSize * | |||
491 | ctk_paper_size_new_custom (const gchar *name, | |||
492 | const gchar *display_name, | |||
493 | gdouble width, | |||
494 | gdouble height, | |||
495 | CtkUnit unit) | |||
496 | { | |||
497 | CtkPaperSize *size; | |||
498 | g_return_val_if_fail (name != NULL, NULL)do { if ((name != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "name != NULL"); return ( ((void*)0)); } } while (0); | |||
499 | g_return_val_if_fail (unit != CTK_UNIT_NONE, NULL)do { if ((unit != CTK_UNIT_NONE)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "unit != CTK_UNIT_NONE") ; return (((void*)0)); } } while (0); | |||
500 | ||||
501 | size = g_slice_new0 (CtkPaperSize)((CtkPaperSize*) g_slice_alloc0 (sizeof (CtkPaperSize))); | |||
502 | ||||
503 | size->name = g_strdup (name)g_strdup_inline (name); | |||
504 | size->display_name = g_strdup (display_name)g_strdup_inline (display_name); | |||
505 | size->is_custom = TRUE(!(0)); | |||
506 | ||||
507 | size->width = _ctk_print_convert_to_mm (width, unit); | |||
508 | size->height = _ctk_print_convert_to_mm (height, unit); | |||
509 | ||||
510 | return size; | |||
511 | } | |||
512 | ||||
513 | /** | |||
514 | * ctk_paper_size_copy: | |||
515 | * @other: a #CtkPaperSize | |||
516 | * | |||
517 | * Copies an existing #CtkPaperSize. | |||
518 | * | |||
519 | * Returns: a copy of @other | |||
520 | * | |||
521 | * Since: 2.10 | |||
522 | */ | |||
523 | CtkPaperSize * | |||
524 | ctk_paper_size_copy (CtkPaperSize *other) | |||
525 | { | |||
526 | CtkPaperSize *size; | |||
527 | ||||
528 | size = g_slice_new0 (CtkPaperSize)((CtkPaperSize*) g_slice_alloc0 (sizeof (CtkPaperSize))); | |||
529 | ||||
530 | size->info = other->info; | |||
531 | if (other->name) | |||
532 | size->name = g_strdup (other->name)g_strdup_inline (other->name); | |||
533 | if (other->display_name) | |||
534 | size->display_name = g_strdup (other->display_name)g_strdup_inline (other->display_name); | |||
535 | if (other->ppd_name) | |||
536 | size->ppd_name = g_strdup (other->ppd_name)g_strdup_inline (other->ppd_name); | |||
537 | ||||
538 | size->width = other->width; | |||
539 | size->height = other->height; | |||
540 | size->is_custom = other->is_custom; | |||
541 | size->is_ipp = other->is_ipp; | |||
542 | ||||
543 | return size; | |||
544 | } | |||
545 | ||||
546 | /** | |||
547 | * ctk_paper_size_free: | |||
548 | * @size: a #CtkPaperSize | |||
549 | * | |||
550 | * Free the given #CtkPaperSize object. | |||
551 | * | |||
552 | * Since: 2.10 | |||
553 | */ | |||
554 | void | |||
555 | ctk_paper_size_free (CtkPaperSize *size) | |||
556 | { | |||
557 | g_free (size->name); | |||
558 | g_free (size->display_name); | |||
559 | g_free (size->ppd_name); | |||
560 | ||||
561 | g_slice_free (CtkPaperSize, size)do { if (1) g_slice_free1 (sizeof (CtkPaperSize), (size)); else (void) ((CtkPaperSize*) 0 == (size)); } while (0); | |||
562 | } | |||
563 | ||||
564 | /** | |||
565 | * ctk_paper_size_is_equal: | |||
566 | * @size1: a #CtkPaperSize object | |||
567 | * @size2: another #CtkPaperSize object | |||
568 | * | |||
569 | * Compares two #CtkPaperSize objects. | |||
570 | * | |||
571 | * Returns: %TRUE, if @size1 and @size2 | |||
572 | * represent the same paper size | |||
573 | * | |||
574 | * Since: 2.10 | |||
575 | */ | |||
576 | gboolean | |||
577 | ctk_paper_size_is_equal (CtkPaperSize *size1, | |||
578 | CtkPaperSize *size2) | |||
579 | { | |||
580 | if (size1->info != NULL((void*)0) && size2->info != NULL((void*)0)) | |||
581 | return size1->info == size2->info; | |||
582 | ||||
583 | return strcmp (ctk_paper_size_get_name (size1), | |||
584 | ctk_paper_size_get_name (size2)) == 0; | |||
585 | } | |||
586 | ||||
587 | /** | |||
588 | * ctk_paper_size_get_paper_sizes: | |||
589 | * @include_custom: whether to include custom paper sizes | |||
590 | * as defined in the page setup dialog | |||
591 | * | |||
592 | * Creates a list of known paper sizes. | |||
593 | * | |||
594 | * Returns: (element-type CtkPaperSize) (transfer full): a newly allocated list of newly | |||
595 | * allocated #CtkPaperSize objects | |||
596 | * | |||
597 | * Since: 2.12 | |||
598 | */ | |||
599 | GList * | |||
600 | ctk_paper_size_get_paper_sizes (gboolean include_custom) | |||
601 | { | |||
602 | GList *list = NULL((void*)0); | |||
603 | guint i; | |||
604 | /* _ctk_load_custom_papers() only on Unix so far */ | |||
605 | #ifdef G_OS_UNIX | |||
606 | if (include_custom) | |||
607 | { | |||
608 | GList *page_setups, *l; | |||
609 | ||||
610 | page_setups = _ctk_load_custom_papers (); | |||
611 | for (l = page_setups; l != NULL((void*)0); l = l->next) | |||
612 | { | |||
613 | CtkPageSetup *setup = (CtkPageSetup *) l->data; | |||
614 | CtkPaperSize *size; | |||
615 | ||||
616 | size = ctk_page_setup_get_paper_size (setup); | |||
617 | list = g_list_prepend (list, ctk_paper_size_copy (size)); | |||
618 | } | |||
619 | ||||
620 | g_list_free_full (page_setups, g_object_unref); | |||
621 | } | |||
622 | #endif | |||
623 | for (i = 0; i < G_N_ELEMENTS (standard_names_offsets)(sizeof (standard_names_offsets) / sizeof ((standard_names_offsets )[0])); ++i) | |||
624 | { | |||
625 | CtkPaperSize *size; | |||
626 | ||||
627 | size = ctk_paper_size_new_from_info (&standard_names_offsets[i]); | |||
628 | list = g_list_prepend (list, size); | |||
629 | } | |||
630 | ||||
631 | return g_list_reverse (list); | |||
632 | } | |||
633 | ||||
634 | ||||
635 | /** | |||
636 | * ctk_paper_size_get_name: | |||
637 | * @size: a #CtkPaperSize object | |||
638 | * | |||
639 | * Gets the name of the #CtkPaperSize. | |||
640 | * | |||
641 | * Returns: the name of @size | |||
642 | * | |||
643 | * Since: 2.10 | |||
644 | */ | |||
645 | const gchar * | |||
646 | ctk_paper_size_get_name (CtkPaperSize *size) | |||
647 | { | |||
648 | if (size->name) | |||
649 | return size->name; | |||
650 | g_assert (size->info != NULL)do { if (size->info != ((void*)0)) ; else g_assertion_message_expr ("Ctk", "ctkpapersize.c", 650, ((const char*) (__func__)), "size->info != NULL" ); } while (0); | |||
651 | return paper_names + size->info->name; | |||
652 | } | |||
653 | ||||
654 | /** | |||
655 | * ctk_paper_size_get_display_name: | |||
656 | * @size: a #CtkPaperSize object | |||
657 | * | |||
658 | * Gets the human-readable name of the #CtkPaperSize. | |||
659 | * | |||
660 | * Returns: the human-readable name of @size | |||
661 | * | |||
662 | * Since: 2.10 | |||
663 | */ | |||
664 | const gchar * | |||
665 | ctk_paper_size_get_display_name (CtkPaperSize *size) | |||
666 | { | |||
667 | const gchar *display_name; | |||
668 | ||||
669 | if (size->display_name) | |||
670 | return size->display_name; | |||
671 | ||||
672 | g_assert (size->info != NULL)do { if (size->info != ((void*)0)) ; else g_assertion_message_expr ("Ctk", "ctkpapersize.c", 672, ((const char*) (__func__)), "size->info != NULL" ); } while (0); | |||
673 | ||||
674 | display_name = paper_names + size->info->display_name; | |||
675 | return g_dpgettext2 (GETTEXT_PACKAGE"ctk30", "paper size", display_name); | |||
676 | } | |||
677 | ||||
678 | /** | |||
679 | * ctk_paper_size_get_ppd_name: | |||
680 | * @size: a #CtkPaperSize object | |||
681 | * | |||
682 | * Gets the PPD name of the #CtkPaperSize, which | |||
683 | * may be %NULL. | |||
684 | * | |||
685 | * Returns: the PPD name of @size | |||
686 | * | |||
687 | * Since: 2.10 | |||
688 | */ | |||
689 | const gchar * | |||
690 | ctk_paper_size_get_ppd_name (CtkPaperSize *size) | |||
691 | { | |||
692 | if (size->ppd_name) | |||
693 | return size->ppd_name; | |||
694 | if (size->info) | |||
695 | return paper_names + size->info->ppd_name; | |||
696 | return NULL((void*)0); | |||
697 | } | |||
698 | ||||
699 | /** | |||
700 | * ctk_paper_size_get_width: | |||
701 | * @size: a #CtkPaperSize object | |||
702 | * @unit: the unit for the return value, not %CTK_UNIT_NONE | |||
703 | * | |||
704 | * Gets the paper width of the #CtkPaperSize, in | |||
705 | * units of @unit. | |||
706 | * | |||
707 | * Returns: the paper width | |||
708 | * | |||
709 | * Since: 2.10 | |||
710 | */ | |||
711 | gdouble | |||
712 | ctk_paper_size_get_width (CtkPaperSize *size, | |||
713 | CtkUnit unit) | |||
714 | { | |||
715 | return _ctk_print_convert_from_mm (size->width, unit); | |||
716 | } | |||
717 | ||||
718 | /** | |||
719 | * ctk_paper_size_get_height: | |||
720 | * @size: a #CtkPaperSize object | |||
721 | * @unit: the unit for the return value, not %CTK_UNIT_NONE | |||
722 | * | |||
723 | * Gets the paper height of the #CtkPaperSize, in | |||
724 | * units of @unit. | |||
725 | * | |||
726 | * Returns: the paper height | |||
727 | * | |||
728 | * Since: 2.10 | |||
729 | */ | |||
730 | gdouble | |||
731 | ctk_paper_size_get_height (CtkPaperSize *size, | |||
732 | CtkUnit unit) | |||
733 | { | |||
734 | return _ctk_print_convert_from_mm (size->height, unit); | |||
735 | } | |||
736 | ||||
737 | /** | |||
738 | * ctk_paper_size_is_custom: | |||
739 | * @size: a #CtkPaperSize object | |||
740 | * | |||
741 | * Returns %TRUE if @size is not a standard paper size. | |||
742 | * | |||
743 | * Returns: whether @size is a custom paper size. | |||
744 | **/ | |||
745 | gboolean | |||
746 | ctk_paper_size_is_custom (CtkPaperSize *size) | |||
747 | { | |||
748 | return size->is_custom; | |||
749 | } | |||
750 | ||||
751 | /** | |||
752 | * ctk_paper_size_is_ipp: | |||
753 | * @size: a #CtkPaperSize object | |||
754 | * | |||
755 | * Returns %TRUE if @size is an IPP standard paper size. | |||
756 | * | |||
757 | * Returns: whether @size is not an IPP custom paper size. | |||
758 | **/ | |||
759 | gboolean | |||
760 | ctk_paper_size_is_ipp (CtkPaperSize *size) | |||
761 | { | |||
762 | return size->is_ipp; | |||
763 | } | |||
764 | ||||
765 | /** | |||
766 | * ctk_paper_size_set_size: | |||
767 | * @size: a custom #CtkPaperSize object | |||
768 | * @width: the new width in units of @unit | |||
769 | * @height: the new height in units of @unit | |||
770 | * @unit: the unit for @width and @height | |||
771 | * | |||
772 | * Changes the dimensions of a @size to @width x @height. | |||
773 | * | |||
774 | * Since: 2.10 | |||
775 | */ | |||
776 | void | |||
777 | ctk_paper_size_set_size (CtkPaperSize *size, | |||
778 | gdouble width, | |||
779 | gdouble height, | |||
780 | CtkUnit unit) | |||
781 | { | |||
782 | 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); | |||
783 | g_return_if_fail (size->is_custom)do { if ((size->is_custom)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "size->is_custom"); return ; } } while (0); | |||
784 | ||||
785 | size->width = _ctk_print_convert_to_mm (width, unit); | |||
786 | size->height = _ctk_print_convert_to_mm (height, unit); | |||
787 | } | |||
788 | ||||
789 | #define NL_PAPER_GET(x)((union { char *string; unsigned int word; })nl_langinfo(x)). word \ | |||
790 | ((union { char *string; unsigned int word; })nl_langinfo(x)).word | |||
791 | ||||
792 | /** | |||
793 | * ctk_paper_size_get_default: | |||
794 | * | |||
795 | * Returns the name of the default paper size, which | |||
796 | * depends on the current locale. | |||
797 | * | |||
798 | * Returns: the name of the default paper size. The string | |||
799 | * is owned by CTK+ and should not be modified. | |||
800 | * | |||
801 | * Since: 2.10 | |||
802 | */ | |||
803 | const gchar * | |||
804 | ctk_paper_size_get_default (void) | |||
805 | { | |||
806 | char *locale, *freeme = NULL((void*)0); | |||
807 | const char *paper_size; | |||
808 | ||||
809 | #if defined(HAVE__NL_PAPER_HEIGHT1) && defined(HAVE__NL_PAPER_WIDTH1) | |||
810 | { | |||
811 | int width = NL_PAPER_GET (_NL_PAPER_WIDTH)((union { char *string; unsigned int word; })nl_langinfo(_NL_PAPER_WIDTH )).word; | |||
812 | int height = NL_PAPER_GET (_NL_PAPER_HEIGHT)((union { char *string; unsigned int word; })nl_langinfo(_NL_PAPER_HEIGHT )).word; | |||
813 | ||||
814 | if (width == 210 && height == 297) | |||
815 | return CTK_PAPER_NAME_A4"iso_a4"; | |||
816 | ||||
817 | if (width == 216 && height == 279) | |||
818 | return CTK_PAPER_NAME_LETTER"na_letter"; | |||
819 | } | |||
820 | #endif | |||
821 | ||||
822 | #ifdef G_OS_WIN32 | |||
823 | freeme = locale = g_win32_getlocale (); | |||
824 | #elif defined(LC_PAPER7) | |||
825 | locale = setlocale(LC_PAPER7, NULL((void*)0)); | |||
826 | #else | |||
827 | locale = setlocale(LC_MESSAGES5, NULL((void*)0)); | |||
828 | #endif | |||
829 | ||||
830 | if (!locale) | |||
831 | return CTK_PAPER_NAME_A4"iso_a4"; | |||
832 | ||||
833 | /* CLDR 1.8.1 | |||
834 | * http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/territory_language_information.html | |||
835 | */ | |||
836 | if (g_regex_match_simple("[^_.@]{2,3}_(BZ|CA|CL|CO|CR|GT|MX|NI|PA|PH|PR|SV|US|VE)", | |||
837 | locale, G_REGEX_ANCHORED, G_REGEX_MATCH_ANCHORED)) | |||
838 | paper_size = CTK_PAPER_NAME_LETTER"na_letter"; | |||
839 | else | |||
840 | paper_size = CTK_PAPER_NAME_A4"iso_a4"; | |||
841 | ||||
842 | g_free (freeme); | |||
843 | return paper_size; | |||
844 | } | |||
845 | ||||
846 | /* These get the default margins used for the paper size. Its | |||
847 | * larger than most printers margins, so that it will be within | |||
848 | * the imageble area on any printer. | |||
849 | * | |||
850 | * I’ve taken the actual values used from the OSX page setup dialog. | |||
851 | * I’m not sure exactly where they got these values for, but might | |||
852 | * correspond to this (from ghostscript docs): | |||
853 | * | |||
854 | * All DeskJets have 0.5 inches (1.27cm) of unprintable bottom margin, | |||
855 | * due to the mechanical arrangement used to grab the paper. Side margins | |||
856 | * are approximately 0.25 inches (0.64cm) for U.S. letter paper, and 0.15 | |||
857 | * inches (0.38cm) for A4. | |||
858 | */ | |||
859 | ||||
860 | /** | |||
861 | * ctk_paper_size_get_default_top_margin: | |||
862 | * @size: a #CtkPaperSize object | |||
863 | * @unit: the unit for the return value, not %CTK_UNIT_NONE | |||
864 | * | |||
865 | * Gets the default top margin for the #CtkPaperSize. | |||
866 | * | |||
867 | * Returns: the default top margin | |||
868 | * | |||
869 | * Since: 2.10 | |||
870 | */ | |||
871 | gdouble | |||
872 | ctk_paper_size_get_default_top_margin (CtkPaperSize *size G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
873 | CtkUnit unit) | |||
874 | { | |||
875 | gdouble margin; | |||
876 | ||||
877 | margin = _ctk_print_convert_to_mm (0.25, CTK_UNIT_INCH); | |||
878 | return _ctk_print_convert_from_mm (margin, unit); | |||
879 | } | |||
880 | ||||
881 | /** | |||
882 | * ctk_paper_size_get_default_bottom_margin: | |||
883 | * @size: a #CtkPaperSize object | |||
884 | * @unit: the unit for the return value, not %CTK_UNIT_NONE | |||
885 | * | |||
886 | * Gets the default bottom margin for the #CtkPaperSize. | |||
887 | * | |||
888 | * Returns: the default bottom margin | |||
889 | * | |||
890 | * Since: 2.10 | |||
891 | */ | |||
892 | gdouble | |||
893 | ctk_paper_size_get_default_bottom_margin (CtkPaperSize *size, | |||
894 | CtkUnit unit) | |||
895 | { | |||
896 | gdouble margin; | |||
897 | const gchar *name; | |||
898 | ||||
899 | margin = _ctk_print_convert_to_mm (0.25, CTK_UNIT_INCH); | |||
900 | ||||
901 | name = ctk_paper_size_get_name (size); | |||
902 | if (strcmp (name, "na_letter") == 0 || | |||
903 | strcmp (name, "na_legal") == 0 || | |||
904 | strcmp (name, "iso_a4") == 0) | |||
905 | margin = _ctk_print_convert_to_mm (0.56, CTK_UNIT_INCH); | |||
906 | ||||
907 | return _ctk_print_convert_from_mm (margin, unit); | |||
908 | } | |||
909 | ||||
910 | /** | |||
911 | * ctk_paper_size_get_default_left_margin: | |||
912 | * @size: a #CtkPaperSize object | |||
913 | * @unit: the unit for the return value, not %CTK_UNIT_NONE | |||
914 | * | |||
915 | * Gets the default left margin for the #CtkPaperSize. | |||
916 | * | |||
917 | * Returns: the default left margin | |||
918 | * | |||
919 | * Since: 2.10 | |||
920 | */ | |||
921 | gdouble | |||
922 | ctk_paper_size_get_default_left_margin (CtkPaperSize *size G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
923 | CtkUnit unit) | |||
924 | { | |||
925 | gdouble margin; | |||
926 | ||||
927 | margin = _ctk_print_convert_to_mm (0.25, CTK_UNIT_INCH); | |||
928 | return _ctk_print_convert_from_mm (margin, unit); | |||
929 | } | |||
930 | ||||
931 | /** | |||
932 | * ctk_paper_size_get_default_right_margin: | |||
933 | * @size: a #CtkPaperSize object | |||
934 | * @unit: the unit for the return value, not %CTK_UNIT_NONE | |||
935 | * | |||
936 | * Gets the default right margin for the #CtkPaperSize. | |||
937 | * | |||
938 | * Returns: the default right margin | |||
939 | * | |||
940 | * Since: 2.10 | |||
941 | */ | |||
942 | gdouble | |||
943 | ctk_paper_size_get_default_right_margin (CtkPaperSize *size G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
944 | CtkUnit unit) | |||
945 | { | |||
946 | gdouble margin; | |||
947 | ||||
948 | margin = _ctk_print_convert_to_mm (0.25, CTK_UNIT_INCH); | |||
949 | return _ctk_print_convert_from_mm (margin, unit); | |||
950 | } | |||
951 | ||||
952 | /** | |||
953 | * ctk_paper_size_new_from_key_file: | |||
954 | * @key_file: the #GKeyFile to retrieve the papersize from | |||
955 | * @group_name: (nullable): the name of the group in the key file to read, | |||
956 | * or %NULL to read the first group | |||
957 | * @error: (allow-none): return location for an error, or %NULL | |||
958 | * | |||
959 | * Reads a paper size from the group @group_name in the key file | |||
960 | * @key_file. | |||
961 | * | |||
962 | * Returns: a new #CtkPaperSize object with the restored | |||
963 | * paper size, or %NULL if an error occurred | |||
964 | * | |||
965 | * Since: 2.12 | |||
966 | */ | |||
967 | CtkPaperSize * | |||
968 | ctk_paper_size_new_from_key_file (GKeyFile *key_file, | |||
969 | const gchar *group_name, | |||
970 | GError **error) | |||
971 | { | |||
972 | CtkPaperSize *paper_size = NULL((void*)0); | |||
973 | gchar *name = NULL((void*)0); | |||
974 | gchar *ppd_name = NULL((void*)0); | |||
975 | gchar *display_name = NULL((void*)0); | |||
976 | gchar *freeme = NULL((void*)0); | |||
977 | gdouble width, height; | |||
978 | GError *err = NULL((void*)0); | |||
979 | ||||
980 | g_return_val_if_fail (key_file != NULL, NULL)do { if ((key_file != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "key_file != NULL"); return (((void*)0)); } } while (0); | |||
981 | ||||
982 | if (!group_name) | |||
983 | group_name = freeme = g_key_file_get_start_group (key_file); | |||
984 | if (!group_name || !g_key_file_has_group (key_file, group_name)) | |||
985 | { | |||
986 | g_set_error_literal (error, | |||
987 | CTK_PRINT_ERRORctk_print_error_quark (), | |||
988 | CTK_PRINT_ERROR_INVALID_FILE, | |||
989 | _("Not a valid page setup file")((char *) g_dgettext ("ctk30", "Not a valid page setup file") )); | |||
990 | goto out; | |||
991 | } | |||
992 | ||||
993 | #define GET_DOUBLE(kf, group, name, v) \ | |||
994 | v = g_key_file_get_double (kf, group, name, &err); \ | |||
995 | if (err != NULL((void*)0)) \ | |||
996 | {\ | |||
997 | g_propagate_error (error, err);\ | |||
998 | goto out;\ | |||
999 | } | |||
1000 | ||||
1001 | GET_DOUBLE (key_file, group_name, "Width", width); | |||
1002 | GET_DOUBLE (key_file, group_name, "Height", height); | |||
1003 | ||||
1004 | #undef GET_DOUBLE | |||
1005 | ||||
1006 | name = g_key_file_get_string (key_file, group_name, | |||
1007 | "Name", NULL((void*)0)); | |||
1008 | ppd_name = g_key_file_get_string (key_file, group_name, | |||
1009 | "PPDName", NULL((void*)0)); | |||
1010 | display_name = g_key_file_get_string (key_file, group_name, | |||
1011 | "DisplayName", NULL((void*)0)); | |||
1012 | /* Fallback for old ~/.ctk-custom-paper entries */ | |||
1013 | if (!display_name) | |||
1014 | display_name = g_strdup (name)g_strdup_inline (name); | |||
1015 | ||||
1016 | if (ppd_name != NULL((void*)0)) | |||
1017 | paper_size = ctk_paper_size_new_from_ppd (ppd_name, | |||
1018 | display_name, | |||
1019 | _ctk_print_convert_from_mm (width, CTK_UNIT_POINTS), | |||
1020 | _ctk_print_convert_from_mm (height, CTK_UNIT_POINTS)); | |||
1021 | else if (name != NULL((void*)0)) | |||
1022 | paper_size = ctk_paper_size_new_custom (name, display_name, | |||
1023 | width, height, CTK_UNIT_MM); | |||
1024 | else | |||
1025 | { | |||
1026 | g_set_error_literal (error, | |||
1027 | CTK_PRINT_ERRORctk_print_error_quark (), | |||
1028 | CTK_PRINT_ERROR_INVALID_FILE, | |||
1029 | _("Not a valid page setup file")((char *) g_dgettext ("ctk30", "Not a valid page setup file") )); | |||
1030 | goto out; | |||
1031 | } | |||
1032 | ||||
1033 | g_assert (paper_size != NULL)do { if (paper_size != ((void*)0)) ; else g_assertion_message_expr ("Ctk", "ctkpapersize.c", 1033, ((const char*) (__func__)), "paper_size != NULL" ); } while (0); | |||
1034 | ||||
1035 | out: | |||
1036 | g_free (ppd_name); | |||
1037 | g_free (name); | |||
1038 | g_free (display_name); | |||
1039 | g_free (freeme); | |||
1040 | ||||
1041 | return paper_size; | |||
1042 | } | |||
1043 | ||||
1044 | /** | |||
1045 | * ctk_paper_size_to_key_file: | |||
1046 | * @size: a #CtkPaperSize | |||
1047 | * @key_file: the #GKeyFile to save the paper size to | |||
1048 | * @group_name: the group to add the settings to in @key_file | |||
1049 | * | |||
1050 | * This function adds the paper size from @size to @key_file. | |||
1051 | * | |||
1052 | * Since: 2.12 | |||
1053 | */ | |||
1054 | void | |||
1055 | ctk_paper_size_to_key_file (CtkPaperSize *size, | |||
1056 | GKeyFile *key_file, | |||
1057 | const gchar *group_name) | |||
1058 | { | |||
1059 | const char *name, *ppd_name, *display_name; | |||
1060 | ||||
1061 | 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); | |||
1062 | 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); | |||
1063 | ||||
1064 | name = ctk_paper_size_get_name (size); | |||
1065 | display_name = ctk_paper_size_get_display_name (size); | |||
1066 | ppd_name = ctk_paper_size_get_ppd_name (size); | |||
1067 | ||||
1068 | if (ppd_name != NULL((void*)0)) | |||
1069 | g_key_file_set_string (key_file, group_name, | |||
1070 | "PPDName", ppd_name); | |||
1071 | else | |||
1072 | g_key_file_set_string (key_file, group_name, | |||
1073 | "Name", name); | |||
1074 | ||||
1075 | if (display_name) | |||
1076 | g_key_file_set_string (key_file, group_name, | |||
1077 | "DisplayName", display_name); | |||
1078 | ||||
1079 | g_key_file_set_double (key_file, group_name, | |||
1080 | "Width", ctk_paper_size_get_width (size, CTK_UNIT_MM)); | |||
1081 | g_key_file_set_double (key_file, group_name, | |||
1082 | "Height", ctk_paper_size_get_height (size, CTK_UNIT_MM)); | |||
1083 | } | |||
1084 | ||||
1085 | /** | |||
1086 | * ctk_paper_size_to_gvariant: | |||
1087 | * @paper_size: a #CtkPaperSize | |||
1088 | * | |||
1089 | * Serialize a paper size to an a{sv} variant. | |||
1090 | * | |||
1091 | * Returns: (transfer none): a new, floating, #GVariant | |||
1092 | * | |||
1093 | * Since: 3.22 | |||
1094 | */ | |||
1095 | GVariant * | |||
1096 | ctk_paper_size_to_gvariant (CtkPaperSize *paper_size) | |||
1097 | { | |||
1098 | const char *name; | |||
1099 | const char *ppd_name; | |||
1100 | const char *display_name; | |||
1101 | GVariantBuilder builder; | |||
1102 | ||||
1103 | g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT((const GVariantType *) "a{sv}")); | |||
1104 | ||||
1105 | name = ctk_paper_size_get_name (paper_size); | |||
1106 | ppd_name = ctk_paper_size_get_ppd_name (paper_size); | |||
1107 | display_name = ctk_paper_size_get_display_name (paper_size); | |||
1108 | ||||
1109 | if (ppd_name != NULL((void*)0)) | |||
1110 | g_variant_builder_add (&builder, "{sv}", "PPDName", g_variant_new_string (ppd_name)); | |||
1111 | else | |||
1112 | g_variant_builder_add (&builder, "{sv}", "Name", g_variant_new_string (name)); | |||
1113 | ||||
1114 | if (display_name != NULL((void*)0)) | |||
1115 | g_variant_builder_add (&builder, "{sv}", "DisplayName", g_variant_new_string (display_name)); | |||
1116 | ||||
1117 | g_variant_builder_add (&builder, "{sv}", "Width", g_variant_new_double (ctk_paper_size_get_width (paper_size, CTK_UNIT_MM))); | |||
1118 | g_variant_builder_add (&builder, "{sv}", "Height", g_variant_new_double (ctk_paper_size_get_height (paper_size, CTK_UNIT_MM))); | |||
1119 | ||||
1120 | return g_variant_builder_end (&builder); | |||
1121 | } | |||
1122 | ||||
1123 | /** | |||
1124 | * ctk_paper_size_new_from_gvariant: | |||
1125 | * @variant: an a{sv} #GVariant | |||
1126 | * | |||
1127 | * Deserialize a paper size from an a{sv} variant in | |||
1128 | * the format produced by ctk_paper_size_to_gvariant(). | |||
1129 | * | |||
1130 | * Returns: (transfer full): a new #CtkPaperSize object | |||
1131 | * | |||
1132 | * Since: 3.22 | |||
1133 | */ | |||
1134 | CtkPaperSize * | |||
1135 | ctk_paper_size_new_from_gvariant (GVariant *variant) | |||
1136 | { | |||
1137 | CtkPaperSize *paper_size; | |||
1138 | const char *name; | |||
1139 | const char *ppd_name; | |||
1140 | const char *display_name; | |||
1141 | gdouble width, height; | |||
1142 | ||||
1143 | 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); | |||
1144 | ||||
1145 | if (!g_variant_lookup (variant, "Width", "d", &width) || | |||
1146 | !g_variant_lookup (variant, "Height", "d", &height)) | |||
1147 | return NULL((void*)0); | |||
1148 | ||||
1149 | if (!g_variant_lookup (variant, "Name", "&s", &name)) | |||
1150 | name = NULL((void*)0); | |||
1151 | ||||
1152 | if (!g_variant_lookup (variant, "PPDName", "&s", &ppd_name)) | |||
1153 | ppd_name = NULL((void*)0); | |||
1154 | ||||
1155 | if (!g_variant_lookup (variant, "DisplayName", "&s", &display_name)) | |||
1156 | display_name = name; | |||
1157 | ||||
1158 | if (ppd_name != NULL((void*)0)) | |||
1159 | paper_size = ctk_paper_size_new_from_ppd (ppd_name, | |||
1160 | display_name, | |||
1161 | _ctk_print_convert_from_mm (width, CTK_UNIT_POINTS), | |||
1162 | _ctk_print_convert_from_mm (height, CTK_UNIT_POINTS)); | |||
1163 | else if (name != NULL((void*)0)) | |||
1164 | paper_size = ctk_paper_size_new_custom (name, display_name, | |||
1165 | width, height, CTK_UNIT_MM); | |||
1166 | else | |||
1167 | paper_size = NULL((void*)0); | |||
1168 | ||||
1169 | return paper_size; | |||
1170 | } |