Bug Summary

File:font-viewer/sushi-font-widget.c
Warning:line 507, column 5
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 sushi-font-widget.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 -pic-is-pie -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/font-viewer -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I .. -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/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/libxml2 -I /usr/include/cafe-desktop-2.0 -I /usr/include/startup-notification-1.0 -I /usr/include/dconf -I ../capplets/common -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/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/libxml2 -I /usr/include/cafe-desktop-2.0 -I /usr/include/startup-notification-1.0 -I /usr/include/dconf -I ../ -D G_LOG_DOMAIN="-properties" -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/polkit-1 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gio-unix-2.0 -D DIRECTORY_DIR="" -D CAFELOCALEDIR="/usr/share/locale" -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/font-viewer -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-04-16-094050-112929-1 -x c sushi-font-widget.c
1/*
2 * Copyright (C) 2011 Red Hat, Inc.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17 * 02111-1307, USA.
18 *
19 * The Sushi project hereby grant permission for non-gpl compatible GStreamer
20 * plugins to be used and distributed together with GStreamer and Sushi. This
21 * permission is above and beyond the permissions granted by the GPL license
22 * Sushi is covered by.
23 *
24 * Authors: Cosimo Cecchi <cosimoc@redhat.com>
25 *
26 */
27
28#include "sushi-font-widget.h"
29#include "sushi-font-loader.h"
30
31#include <math.h>
32
33enum {
34 PROP_URI = 1,
35 PROP_FACE_INDEX,
36 NUM_PROPERTIES
37};
38
39enum {
40 LOADED,
41 ERROR,
42 NUM_SIGNALS
43};
44
45struct _SushiFontWidgetPrivate {
46 gchar *uri;
47 gint face_index;
48
49 FT_Library library;
50 FT_Face face;
51 gchar *face_contents;
52
53 const gchar *lowercase_text;
54 const gchar *uppercase_text;
55 const gchar *punctuation_text;
56
57 gchar *sample_string;
58
59 gchar *font_name;
60};
61
62static GParamSpec *properties[NUM_PROPERTIES] = { NULL((void*)0), };
63static guint signals[NUM_SIGNALS] = { 0, };
64
65G_DEFINE_TYPE_WITH_PRIVATE (SushiFontWidget, sushi_font_widget, CTK_TYPE_DRAWING_AREA)static void sushi_font_widget_init (SushiFontWidget *self); static
void sushi_font_widget_class_init (SushiFontWidgetClass *klass
); static GType sushi_font_widget_get_type_once (void); static
gpointer sushi_font_widget_parent_class = ((void*)0); static
gint SushiFontWidget_private_offset; static void sushi_font_widget_class_intern_init
(gpointer klass) { sushi_font_widget_parent_class = g_type_class_peek_parent
(klass); if (SushiFontWidget_private_offset != 0) g_type_class_adjust_private_offset
(klass, &SushiFontWidget_private_offset); sushi_font_widget_class_init
((SushiFontWidgetClass*) klass); } __attribute__ ((__unused__
)) static inline gpointer sushi_font_widget_get_instance_private
(SushiFontWidget *self) { return (((gpointer) ((guint8*) (self
) + (glong) (SushiFontWidget_private_offset)))); } GType sushi_font_widget_get_type
(void) { static gsize 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 (&static_g_define_type_id
)); }))) { GType g_define_type_id = sushi_font_widget_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 ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType sushi_font_widget_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((ctk_drawing_area_get_type ()), g_intern_static_string ("SushiFontWidget"
), sizeof (SushiFontWidgetClass), (GClassInitFunc)(void (*)(void
)) sushi_font_widget_class_intern_init, sizeof (SushiFontWidget
), (GInstanceInitFunc)(void (*)(void)) sushi_font_widget_init
, (GTypeFlags) 0); { {{ SushiFontWidget_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (SushiFontWidgetPrivate)); };} } return
g_define_type_id; }
;
66
67#define SURFACE_SIZE4 4
68#define SECTION_SPACING16 16
69#define LINE_SPACING2 2
70
71static const gchar lowercase_text_stock[] = "abcdefghijklmnopqrstuvwxyz";
72static const gchar uppercase_text_stock[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
73static const gchar punctuation_text_stock[] = "0123456789.:,;(*!?')";
74
75/* adapted from gnome-utils:font-viewer/font-view.c
76 *
77 * Copyright (C) 2002-2003 James Henstridge <james@daa.com.au>
78 * Copyright (C) 2010 Cosimo Cecchi <cosimoc@gnome.org>
79 *
80 * License: GPLv2+
81 */
82static void
83draw_string (SushiFontWidget *self,
84 cairo_t *cr,
85 CtkBorder padding,
86 const gchar *text,
87 gint *pos_y)
88{
89 cairo_font_extents_t font_extents;
90 cairo_text_extents_t extents;
91 CtkTextDirection text_dir;
92 gint pos_x;
93
94 text_dir = ctk_widget_get_direction (CTK_WIDGET (self)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((self)), ((ctk_widget_get_type ()))))))
);
95
96 cairo_font_extents (cr, &font_extents);
97 cairo_text_extents (cr, text, &extents);
98
99 if (pos_y != NULL((void*)0))
100 *pos_y += font_extents.ascent + font_extents.descent +
101 extents.y_advance + LINE_SPACING2 / 2;
102 if (text_dir == CTK_TEXT_DIR_LTR)
103 pos_x = padding.left;
104 else {
105 pos_x = ctk_widget_get_allocated_width (CTK_WIDGET (self)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((self)), ((ctk_widget_get_type ()))))))
) -
106 extents.x_advance - padding.right;
107 }
108
109 cairo_move_to (cr, pos_x, *pos_y);
110 cairo_show_text (cr, text);
111
112 *pos_y += LINE_SPACING2 / 2;
113}
114
115static gboolean
116check_font_contain_text (FT_Face face,
117 const gchar *text)
118{
119 gunichar *string;
120 glong len, idx, map;
121 FT_CharMap charmap;
122 gboolean retval = FALSE(0);
123
124 string = g_utf8_to_ucs4_fast (text, -1, &len);
125
126 for (map = 0; map < face->num_charmaps; map++) {
127 charmap = face->charmaps[map];
128 FT_Set_Charmap (face, charmap);
129
130 retval = TRUE(!(0));
131
132 for (idx = 0; idx < len; idx++) {
133 gunichar c = string[idx];
134
135 if (!FT_Get_Char_Index (face, c)) {
136 retval = FALSE(0);
137 break;
138 }
139 }
140
141 if (retval)
142 break;
143 }
144
145 g_free (string);
146
147 return retval;
148}
149
150static gchar *
151build_charlist_for_face (FT_Face face,
152 gint *length)
153{
154 GString *string;
155 gulong c;
156 guint glyph;
157 gint total_chars = 0;
158
159 string = g_string_new (NULL((void*)0));
160
161 c = FT_Get_First_Char (face, &glyph);
162
163 while (glyph != 0) {
164 g_string_append_unichar (string, (gunichar) c);
165 c = FT_Get_Next_Char (face, c, &glyph);
166 total_chars++;
167 }
168
169 if (length)
170 *length = total_chars;
171
172 return g_string_free (string, FALSE)(__builtin_constant_p ((0)) ? (((0)) ? (g_string_free) ((string
), ((0))) : g_string_free_and_steal (string)) : (g_string_free
) ((string), ((0))))
;
173}
174
175static gchar *
176random_string_from_available_chars (FT_Face face,
177 gint n_chars)
178{
179 gchar *chars;
180 gint idx, rand, total_chars;
181 GString *retval;
182 gchar *ptr, *end;
183
184 idx = 0;
185 chars = build_charlist_for_face (face, &total_chars);
186
187 if (total_chars == 0)
188 return NULL((void*)0);
189
190 retval = g_string_new (NULL((void*)0));
191
192 while (idx < n_chars) {
193 rand = g_random_int_range (0, total_chars);
194
195 ptr = g_utf8_offset_to_pointer (chars, rand);
196 end = g_utf8_find_next_char (ptr, NULL((void*)0));
197
198 g_string_append_len (retval, ptr, end - ptr)g_string_append_len_inline (retval, ptr, end - ptr);
199 idx++;
200 }
201
202 return g_string_free (retval, FALSE)(__builtin_constant_p ((0)) ? (((0)) ? (g_string_free) ((retval
), ((0))) : g_string_free_and_steal (retval)) : (g_string_free
) ((retval), ((0))))
;
203}
204
205static gboolean
206set_pango_sample_string (SushiFontWidget *self)
207{
208 const gchar *sample_string;
209 gboolean retval = FALSE(0);
210
211 sample_string = pango_language_get_sample_string (pango_language_from_string (NULL((void*)0)));
212 if (check_font_contain_text (self->priv->face, sample_string))
213 retval = TRUE(!(0));
214
215 if (!retval) {
216 sample_string = pango_language_get_sample_string (pango_language_from_string ("C"));
217 if (check_font_contain_text (self->priv->face, sample_string))
218 retval = TRUE(!(0));
219 }
220
221 if (retval) {
222 g_free (self->priv->sample_string);
223 self->priv->sample_string = g_strdup (sample_string)g_strdup_inline (sample_string);
224 }
225
226 return retval;
227}
228
229static void
230build_strings_for_face (SushiFontWidget *self)
231{
232 /* if we don't have lowercase/uppercase/punctuation text in the face,
233 * we omit it directly, and render a random text below.
234 */
235 if (check_font_contain_text (self->priv->face, lowercase_text_stock))
236 self->priv->lowercase_text = lowercase_text_stock;
237 else
238 self->priv->lowercase_text = NULL((void*)0);
239
240 if (check_font_contain_text (self->priv->face, uppercase_text_stock))
241 self->priv->uppercase_text = uppercase_text_stock;
242 else
243 self->priv->uppercase_text = NULL((void*)0);
244
245 if (check_font_contain_text (self->priv->face, punctuation_text_stock))
246 self->priv->punctuation_text = punctuation_text_stock;
247 else
248 self->priv->punctuation_text = NULL((void*)0);
249
250 if (!set_pango_sample_string (self))
251 self->priv->sample_string = random_string_from_available_chars (self->priv->face, 36);
252
253 g_free (self->priv->font_name);
254 self->priv->font_name = NULL((void*)0);
255
256 if (self->priv->face->family_name != NULL((void*)0)) {
257 gchar *font_name =
258 g_strconcat (self->priv->face->family_name, " ",
259 self->priv->face->style_name, NULL((void*)0));
260
261 if (check_font_contain_text (self->priv->face, font_name))
262 self->priv->font_name = font_name;
263 else
264 g_free (font_name);
265 }
266}
267
268static gint *
269build_sizes_table (FT_Face face,
270 gint *n_sizes,
271 gint *alpha_size,
272 gint *title_size)
273{
274 gint *sizes = NULL((void*)0);
275 gint i;
276
277 /* work out what sizes to render */
278 if (FT_IS_SCALABLE (face)( !!( (face)->face_flags & ( 1L << 0 ) ) )) {
5
Assuming the condition is true
6
Taking false branch
279 *n_sizes = 14;
280 sizes = g_new (gint, *n_sizes)((gint *) g_malloc_n ((*n_sizes), sizeof (gint)));
281 sizes[0] = 8;
282 sizes[1] = 10;
283 sizes[2] = 12;
284 sizes[3] = 18;
285 sizes[4] = 24;
286 sizes[5] = 36;
287 sizes[6] = 48;
288 sizes[7] = 72;
289 sizes[8] = 96;
290 sizes[9] = 120;
291 sizes[10] = 144;
292 sizes[11] = 168;
293 sizes[12] = 192;
294 sizes[13] = 216;
295
296 *alpha_size = 24;
297 *title_size = 48;
298 } else {
299 gint alpha_diff = G_MAXINT2147483647;
300 gint title_diff = G_MAXINT2147483647;
301
302 /* use fixed sizes */
303 *n_sizes = face->num_fixed_sizes;
304 sizes = g_new (gint, *n_sizes)((gint *) g_malloc_n ((*n_sizes), sizeof (gint)));
305 *alpha_size = 0;
306
307 for (i = 0; i < face->num_fixed_sizes; i++) {
7
Assuming 'i' is >= field 'num_fixed_sizes'
8
Loop condition is false. Execution continues on line 321
308 sizes[i] = face->available_sizes[i].height;
309
310 if ((gint) (abs (sizes[i] - 24)) < alpha_diff) {
311 alpha_diff = (gint) abs (sizes[i] - 24);
312 *alpha_size = sizes[i];
313 }
314 if ((gint) (abs (sizes[i] - 24)) < title_diff) {
315 title_diff = (gint) abs (sizes[i] - 24);
316 *title_size = sizes[i];
317 }
318 }
319 }
320
321 return sizes;
9
Returning without writing to '*title_size'
322}
323
324static void
325sushi_font_widget_size_request (CtkWidget *drawing_area,
326 gint *width,
327 gint *height,
328 gint *min_height)
329{
330 SushiFontWidget *self = SUSHI_FONT_WIDGET (drawing_area)((((SushiFontWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((drawing_area)), ((sushi_font_widget_get_type ()))))))
;
331 SushiFontWidgetPrivate *priv = self->priv;
332 gint i, pixmap_width, pixmap_height;
333 cairo_text_extents_t extents;
334 cairo_font_extents_t font_extents;
335 cairo_font_face_t *font;
336 gint *sizes = NULL((void*)0), n_sizes, alpha_size, title_size;
337 cairo_t *cr;
338 cairo_surface_t *surface;
339 FT_Face face = priv->face;
340 CtkStyleContext *context;
341 CtkStateFlags state;
342 CtkBorder padding;
343
344 if (face == NULL((void*)0)) {
345 if (width != NULL((void*)0))
346 *width = 1;
347 if (height != NULL((void*)0))
348 *height = 1;
349 if (min_height != NULL((void*)0))
350 *min_height = 1;
351
352 return;
353 }
354
355 if (min_height != NULL((void*)0))
356 *min_height = -1;
357
358 surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
359 SURFACE_SIZE4, SURFACE_SIZE4);
360 cr = cairo_create (surface);
361 context = ctk_widget_get_style_context (drawing_area);
362 state = ctk_style_context_get_state (context);
363 ctk_style_context_get_padding (context, state, &padding);
364
365 sizes = build_sizes_table (face, &n_sizes, &alpha_size, &title_size);
366
367 /* calculate size of pixmap to use */
368 pixmap_width = padding.left + padding.right;
369 pixmap_height = padding.top + padding.bottom;
370
371 font = cairo_ft_font_face_create_for_ft_face (face, 0);
372 cairo_set_font_face (cr, font);
373 cairo_font_face_destroy (font);
374
375 if (self->priv->font_name != NULL((void*)0)) {
376 cairo_set_font_size (cr, title_size);
377 cairo_font_extents (cr, &font_extents);
378 cairo_text_extents (cr, self->priv->font_name, &extents);
379 pixmap_height += font_extents.ascent + font_extents.descent +
380 extents.y_advance + LINE_SPACING2;
381 pixmap_width = MAX (pixmap_width, extents.width + padding.left + padding.right)(((pixmap_width) > (extents.width + padding.left + padding
.right)) ? (pixmap_width) : (extents.width + padding.left + padding
.right))
;
382 }
383
384 pixmap_height += SECTION_SPACING16 / 2;
385 cairo_set_font_size (cr, alpha_size);
386 cairo_font_extents (cr, &font_extents);
387
388 if (self->priv->lowercase_text != NULL((void*)0)) {
389 cairo_text_extents (cr, self->priv->lowercase_text, &extents);
390 pixmap_height += font_extents.ascent + font_extents.descent +
391 extents.y_advance + LINE_SPACING2;
392 pixmap_width = MAX (pixmap_width, extents.width + padding.left + padding.right)(((pixmap_width) > (extents.width + padding.left + padding
.right)) ? (pixmap_width) : (extents.width + padding.left + padding
.right))
;
393 }
394
395 if (self->priv->uppercase_text != NULL((void*)0)) {
396 cairo_text_extents (cr, self->priv->uppercase_text, &extents);
397 pixmap_height += font_extents.ascent + font_extents.descent +
398 extents.y_advance + LINE_SPACING2;
399 pixmap_width = MAX (pixmap_width, extents.width + padding.left + padding.right)(((pixmap_width) > (extents.width + padding.left + padding
.right)) ? (pixmap_width) : (extents.width + padding.left + padding
.right))
;
400 }
401
402 if (self->priv->punctuation_text != NULL((void*)0)) {
403 cairo_text_extents (cr, self->priv->punctuation_text, &extents);
404 pixmap_height += font_extents.ascent + font_extents.descent +
405 extents.y_advance + LINE_SPACING2;
406 pixmap_width = MAX (pixmap_width, extents.width + padding.left + padding.right)(((pixmap_width) > (extents.width + padding.left + padding
.right)) ? (pixmap_width) : (extents.width + padding.left + padding
.right))
;
407 }
408
409 if (self->priv->sample_string != NULL((void*)0)) {
410 pixmap_height += SECTION_SPACING16;
411
412 for (i = 0; i < n_sizes; i++) {
413 cairo_set_font_size (cr, sizes[i]);
414 cairo_font_extents (cr, &font_extents);
415 cairo_text_extents (cr, self->priv->sample_string, &extents);
416 pixmap_height += font_extents.ascent + font_extents.descent +
417 extents.y_advance + LINE_SPACING2;
418 pixmap_width = MAX (pixmap_width, extents.width + padding.left + padding.right)(((pixmap_width) > (extents.width + padding.left + padding
.right)) ? (pixmap_width) : (extents.width + padding.left + padding
.right))
;
419
420 if ((i == 7) && (min_height != NULL((void*)0)))
421 *min_height = pixmap_height;
422 }
423 }
424
425 pixmap_height += padding.bottom + SECTION_SPACING16;
426
427 if (min_height != NULL((void*)0) && *min_height == -1)
428 *min_height = pixmap_height;
429
430 if (width != NULL((void*)0))
431 *width = pixmap_width;
432
433 if (height != NULL((void*)0))
434 *height = pixmap_height;
435
436 cairo_destroy (cr);
437 cairo_surface_destroy (surface);
438 g_free (sizes);
439}
440
441static void
442sushi_font_widget_get_preferred_width (CtkWidget *drawing_area,
443 gint *minimum_width,
444 gint *natural_width)
445{
446 gint width;
447
448 sushi_font_widget_size_request (drawing_area, &width, NULL((void*)0), NULL((void*)0));
449
450 *minimum_width = *natural_width = width;
451}
452
453static void
454sushi_font_widget_get_preferred_height (CtkWidget *drawing_area,
455 gint *minimum_height,
456 gint *natural_height)
457{
458 gint height, min_height;
459
460 sushi_font_widget_size_request (drawing_area, NULL((void*)0), &height, &min_height);
461
462 *minimum_height = min_height;
463 *natural_height = height;
464}
465
466static gboolean
467sushi_font_widget_draw (CtkWidget *drawing_area,
468 cairo_t *cr)
469{
470 SushiFontWidget *self = SUSHI_FONT_WIDGET (drawing_area)((((SushiFontWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((drawing_area)), ((sushi_font_widget_get_type ()))))))
;
471 SushiFontWidgetPrivate *priv = self->priv;
472 gint *sizes = NULL((void*)0), n_sizes, alpha_size, title_size, pos_y = 0, i;
1
'title_size' declared without an initial value
473 cairo_font_face_t *font;
474 FT_Face face = priv->face;
475 CtkStyleContext *context;
476 CdkRGBA color;
477 CtkBorder padding;
478 CtkStateFlags state;
479 gint allocated_width, allocated_height;
480
481 if (face == NULL((void*)0))
2
Assuming 'face' is not equal to NULL
3
Taking false branch
482 goto end;
483
484 context = ctk_widget_get_style_context (drawing_area);
485 state = ctk_style_context_get_state (context);
486
487 allocated_width = ctk_widget_get_allocated_width (drawing_area);
488 allocated_height = ctk_widget_get_allocated_height (drawing_area);
489
490 ctk_render_background (context, cr,
491 0, 0, allocated_width, allocated_height);
492
493 ctk_style_context_get_color (context, state, &color);
494 ctk_style_context_get_padding (context, state, &padding);
495
496 cdk_cairo_set_source_rgba (cr, &color);
497
498 sizes = build_sizes_table (face, &n_sizes, &alpha_size, &title_size);
4
Calling 'build_sizes_table'
10
Returning from 'build_sizes_table'
499
500 font = cairo_ft_font_face_create_for_ft_face (face, 0);
501 cairo_set_font_face (cr, font);
502 cairo_font_face_destroy (font);
503
504 /* draw text */
505
506 if (self->priv->font_name != NULL((void*)0)) {
11
Assuming field 'font_name' is not equal to NULL
12
Taking true branch
507 cairo_set_font_size (cr, title_size);
13
2nd function call argument is an uninitialized value
508 draw_string (self, cr, padding, self->priv->font_name, &pos_y);
509 }
510
511 if (pos_y > allocated_height)
512 goto end;
513
514 pos_y += SECTION_SPACING16 / 2;
515 cairo_set_font_size (cr, alpha_size);
516
517 if (self->priv->lowercase_text != NULL((void*)0))
518 draw_string (self, cr, padding, self->priv->lowercase_text, &pos_y);
519 if (pos_y > allocated_height)
520 goto end;
521
522 if (self->priv->uppercase_text != NULL((void*)0))
523 draw_string (self, cr, padding, self->priv->uppercase_text, &pos_y);
524 if (pos_y > allocated_height)
525 goto end;
526
527 if (self->priv->punctuation_text != NULL((void*)0))
528 draw_string (self, cr, padding, self->priv->punctuation_text, &pos_y);
529 if (pos_y > allocated_height)
530 goto end;
531
532 pos_y += SECTION_SPACING16;
533
534 for (i = 0; i < n_sizes; i++) {
535 cairo_set_font_size (cr, sizes[i]);
536 draw_string (self, cr, padding, self->priv->sample_string, &pos_y);
537 if (pos_y > allocated_height)
538 break;
539 }
540
541 end:
542 g_free (sizes);
543
544 return FALSE(0);
545}
546
547static void
548font_face_async_ready_cb (GObject *object,
549 GAsyncResult *result,
550 gpointer user_data)
551{
552 SushiFontWidget *self = user_data;
553 GError *error = NULL((void*)0);
554
555 self->priv->face =
556 sushi_new_ft_face_from_uri_finish (result,
557 &self->priv->face_contents,
558 &error);
559
560 if (error != NULL((void*)0)) {
561 g_signal_emit (self, signals[ERROR], 0, error->message);
562 g_print ("Can't load the font face: %s\n", error->message);
563 g_error_free (error);
564
565 return;
566 }
567
568 build_strings_for_face (self);
569
570 ctk_widget_queue_resize (CTK_WIDGET (self)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((self)), ((ctk_widget_get_type ()))))))
);
571 g_signal_emit (self, signals[LOADED], 0);
572}
573
574void
575sushi_font_widget_load (SushiFontWidget *self)
576{
577 sushi_new_ft_face_from_uri_async (self->priv->library,
578 self->priv->uri,
579 self->priv->face_index,
580 font_face_async_ready_cb,
581 self);
582}
583
584static void
585sushi_font_widget_init (SushiFontWidget *self)
586{
587 FT_Error err;
588
589 self->priv = sushi_font_widget_get_instance_private (self);
590
591 self->priv->face = NULL((void*)0);
592 err = FT_Init_FreeType (&self->priv->library);
593
594 if (err != FT_Err_Ok)
595 g_error ("Unable to initialize FreeType");
596
597 ctk_style_context_add_class (ctk_widget_get_style_context (CTK_WIDGET (self)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((self)), ((ctk_widget_get_type ()))))))
),
598 CTK_STYLE_CLASS_VIEW"view");
599}
600
601static void
602sushi_font_widget_get_property (GObject *object,
603 guint prop_id,
604 GValue *value,
605 GParamSpec *pspec)
606{
607 SushiFontWidget *self = SUSHI_FONT_WIDGET (object)((((SushiFontWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((sushi_font_widget_get_type ()))))))
;
608
609 switch (prop_id) {
610 case PROP_URI:
611 g_value_set_string (value, self->priv->uri);
612 break;
613 case PROP_FACE_INDEX:
614 g_value_set_int (value, self->priv->face_index);
615 break;
616 default:
617 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'"
, "sushi-font-widget.c", 617, ("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)
;
618 break;
619 }
620}
621
622static void
623sushi_font_widget_set_property (GObject *object,
624 guint prop_id,
625 const GValue *value,
626 GParamSpec *pspec)
627{
628 SushiFontWidget *self = SUSHI_FONT_WIDGET (object)((((SushiFontWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((sushi_font_widget_get_type ()))))))
;
629
630 switch (prop_id) {
631 case PROP_URI:
632 self->priv->uri = g_value_dup_string (value);
633 break;
634 case PROP_FACE_INDEX:
635 self->priv->face_index = g_value_get_int (value);
636 break;
637 default:
638 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'"
, "sushi-font-widget.c", 638, ("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)
;
639 break;
640 }
641}
642
643static void
644sushi_font_widget_finalize (GObject *object)
645{
646 SushiFontWidget *self = SUSHI_FONT_WIDGET (object)((((SushiFontWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((sushi_font_widget_get_type ()))))))
;
647
648 g_free (self->priv->uri);
649
650 if (self->priv->face != NULL((void*)0)) {
651 FT_Done_Face (self->priv->face);
652 self->priv->face = NULL((void*)0);
653 }
654
655 g_free (self->priv->font_name);
656 g_free (self->priv->sample_string);
657 g_free (self->priv->face_contents);
658
659 if (self->priv->library != NULL((void*)0)) {
660 FT_Done_FreeType (self->priv->library);
661 self->priv->library = NULL((void*)0);
662 }
663
664 G_OBJECT_CLASS (sushi_font_widget_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((sushi_font_widget_parent_class)), (((GType) ((20) <<
(2))))))))
->finalize (object);
665}
666
667static void
668sushi_font_widget_constructed (GObject *object)
669{
670 SushiFontWidget *self = SUSHI_FONT_WIDGET (object)((((SushiFontWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((sushi_font_widget_get_type ()))))))
;
671
672 sushi_font_widget_load (self);
673
674 G_OBJECT_CLASS (sushi_font_widget_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((sushi_font_widget_parent_class)), (((GType) ((20) <<
(2))))))))
->constructed (object);
675}
676
677static void
678sushi_font_widget_class_init (SushiFontWidgetClass *klass)
679{
680 GObjectClass *oclass = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
681 CtkWidgetClass *wclass = CTK_WIDGET_CLASS (klass)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), ((ctk_widget_get_type ()))))))
;
682
683 oclass->finalize = sushi_font_widget_finalize;
684 oclass->set_property = sushi_font_widget_set_property;
685 oclass->get_property = sushi_font_widget_get_property;
686 oclass->constructed = sushi_font_widget_constructed;
687
688 wclass->draw = sushi_font_widget_draw;
689 wclass->get_preferred_width = sushi_font_widget_get_preferred_width;
690 wclass->get_preferred_height = sushi_font_widget_get_preferred_height;
691
692 properties[PROP_URI] =
693 g_param_spec_string ("uri",
694 "Uri", "Uri",
695 NULL((void*)0), G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
696 properties[PROP_FACE_INDEX] =
697 g_param_spec_int ("face-index",
698 "Face index", "Face index",
699 0, G_MAXINT2147483647,
700 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
701
702 signals[LOADED] =
703 g_signal_new ("loaded",
704 G_TYPE_FROM_CLASS (klass)(((GTypeClass*) (klass))->g_type),
705 G_SIGNAL_RUN_FIRST,
706 0, NULL((void*)0), NULL((void*)0),
707 g_cclosure_marshal_VOID__VOID,
708 G_TYPE_NONE((GType) ((1) << (2))), 0);
709 signals[ERROR] =
710 g_signal_new ("error",
711 G_TYPE_FROM_CLASS (klass)(((GTypeClass*) (klass))->g_type),
712 G_SIGNAL_RUN_FIRST,
713 0, NULL((void*)0), NULL((void*)0),
714 g_cclosure_marshal_VOID__STRING,
715 G_TYPE_NONE((GType) ((1) << (2))), 1, G_TYPE_STRING((GType) ((16) << (2))));
716
717 g_object_class_install_properties (oclass, NUM_PROPERTIES, properties);
718}
719
720SushiFontWidget *
721sushi_font_widget_new (const gchar *uri, gint face_index)
722{
723 return g_object_new (SUSHI_TYPE_FONT_WIDGET(sushi_font_widget_get_type ()),
724 "uri", uri,
725 "face-index", face_index,
726 NULL((void*)0));
727}
728
729/**
730 * sushi_font_widget_get_ft_face: (skip)
731 *
732 */
733FT_Face
734sushi_font_widget_get_ft_face (SushiFontWidget *self)
735{
736 return self->priv->face;
737}
738
739const gchar *
740sushi_font_widget_get_uri (SushiFontWidget *self)
741{
742 return self->priv->uri;
743}
744