Evince
Evince is a document viewer capable of displaying multiple and single page document formats like PDF and Postscript.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
gd-two-lines-renderer.c File Reference
#include "gd-two-lines-renderer.h"
#include <string.h>
+ Include dependency graph for gd-two-lines-renderer.c:

Go to the source code of this file.

Data Structures

struct  _GdTwoLinesRendererPrivate
 

Enumerations

enum  { PROP_TEXT_LINES = 1, PROP_LINE_TWO, NUM_PROPERTIES }
 

Functions

static PangoLayout * create_layout_with_attrs (GtkWidget *widget, const GdkRectangle *cell_area, GdTwoLinesRenderer *self, PangoEllipsizeMode ellipsize)
 
static void gd_two_lines_renderer_prepare_layouts (GdTwoLinesRenderer *self, const GdkRectangle *cell_area, GtkWidget *widget, PangoLayout **layout_one, PangoLayout **layout_two)
 
static void gd_two_lines_renderer_get_size (GtkCellRenderer *cell, GtkWidget *widget, PangoLayout *layout_1, PangoLayout *layout_2, gint *width, gint *height, const GdkRectangle *cell_area, gint *x_offset_1, gint *x_offset_2, gint *y_offset)
 
static void gd_two_lines_renderer_render (GtkCellRenderer *cell, cairo_t *cr, GtkWidget *widget, const GdkRectangle *background_area, const GdkRectangle *cell_area, GtkCellRendererState flags)
 
static void gd_two_lines_renderer_get_preferred_width (GtkCellRenderer *cell, GtkWidget *widget, gint *minimum_size, gint *natural_size)
 
static void gd_two_lines_renderer_get_preferred_height_for_width (GtkCellRenderer *cell, GtkWidget *widget, gint width, gint *minimum_size, gint *natural_size)
 
static void gd_two_lines_renderer_get_preferred_height (GtkCellRenderer *cell, GtkWidget *widget, gint *minimum_size, gint *natural_size)
 
static void gd_two_lines_renderer_get_aligned_area (GtkCellRenderer *cell, GtkWidget *widget, GtkCellRendererState flags, const GdkRectangle *cell_area, GdkRectangle *aligned_area)
 
static void gd_two_lines_renderer_set_line_two (GdTwoLinesRenderer *self, const gchar *line_two)
 
static void gd_two_lines_renderer_set_text_lines (GdTwoLinesRenderer *self, gint text_lines)
 
static void gd_two_lines_renderer_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
 
static void gd_two_lines_renderer_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
 
static void gd_two_lines_renderer_finalize (GObject *object)
 
static void gd_two_lines_renderer_class_init (GdTwoLinesRendererClass *klass)
 
static void gd_two_lines_renderer_init (GdTwoLinesRenderer *self)
 
GtkCellRenderer * gd_two_lines_renderer_new (void)
 

Variables

static GParamSpec * properties [NUM_PROPERTIES] = { NULL, }
 

Enumeration Type Documentation

anonymous enum
Enumerator
PROP_TEXT_LINES 
PROP_LINE_TWO 
NUM_PROPERTIES 

Definition at line 32 of file gd-two-lines-renderer.c.

32  {
33  PROP_TEXT_LINES = 1,
36 };

Function Documentation

static PangoLayout* create_layout_with_attrs ( GtkWidget *  widget,
const GdkRectangle *  cell_area,
GdTwoLinesRenderer self,
PangoEllipsizeMode  ellipsize 
)
static

Definition at line 41 of file gd-two-lines-renderer.c.

45 {
46  PangoLayout *layout;
47  gint wrap_width, xpad;
48  PangoWrapMode wrap_mode;
49  PangoAlignment alignment;
50 
51  g_object_get (self,
52  "wrap-width", &wrap_width,
53  "wrap-mode", &wrap_mode,
54  "alignment", &alignment,
55  "xpad", &xpad,
56  NULL);
57 
58  layout = pango_layout_new (gtk_widget_get_pango_context (widget));
59 
60  pango_layout_set_ellipsize (layout, ellipsize);
61  pango_layout_set_alignment (layout, alignment);
62 
63  if (wrap_width != -1)
64  {
65  pango_layout_set_width (layout, wrap_width * PANGO_SCALE);
66  pango_layout_set_wrap (layout, wrap_mode);
67  }
68  else
69  {
70  if (cell_area != NULL)
71  pango_layout_set_width (layout, (cell_area->width - 2 * xpad) * PANGO_SCALE);
72  else
73  pango_layout_set_width (layout, -1);
74 
75  pango_layout_set_wrap (layout, PANGO_WRAP_CHAR);
76  }
77 
78  return layout;
79 }

+ Here is the caller graph for this function:

static void gd_two_lines_renderer_class_init ( GdTwoLinesRendererClass klass)
static

Definition at line 535 of file gd-two-lines-renderer.c.

536 {
537  GtkCellRendererClass *cclass = GTK_CELL_RENDERER_CLASS (klass);
538  GObjectClass *oclass = G_OBJECT_CLASS (klass);
539 
540  cclass->render = gd_two_lines_renderer_render;
541  cclass->get_preferred_width = gd_two_lines_renderer_get_preferred_width;
542  cclass->get_preferred_height = gd_two_lines_renderer_get_preferred_height;
543  cclass->get_preferred_height_for_width = gd_two_lines_renderer_get_preferred_height_for_width;
544  cclass->get_aligned_area = gd_two_lines_renderer_get_aligned_area;
545 
546  oclass->set_property = gd_two_lines_renderer_set_property;
547  oclass->get_property = gd_two_lines_renderer_get_property;
548  oclass->finalize = gd_two_lines_renderer_finalize;
549 
551  g_param_spec_int ("text-lines",
552  "Lines of text",
553  "The total number of lines to be displayed",
554  2, G_MAXINT, 2,
555  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
556 
558  g_param_spec_string ("line-two",
559  "Second line",
560  "Second line",
561  NULL,
562  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
563 
564  g_type_class_add_private (klass, sizeof (GdTwoLinesRendererPrivate));
565  g_object_class_install_properties (oclass, NUM_PROPERTIES, properties);
566 }
static void gd_two_lines_renderer_finalize ( GObject *  object)
static

Definition at line 525 of file gd-two-lines-renderer.c.

526 {
527  GdTwoLinesRenderer *self = GD_TWO_LINES_RENDERER (object);
528 
529  g_free (self->priv->line_two);
530 
531  G_OBJECT_CLASS (gd_two_lines_renderer_parent_class)->finalize (object);
532 }

+ Here is the caller graph for this function:

static void gd_two_lines_renderer_get_aligned_area ( GtkCellRenderer *  cell,
GtkWidget *  widget,
GtkCellRendererState  flags,
const GdkRectangle *  cell_area,
GdkRectangle *  aligned_area 
)
static

Definition at line 429 of file gd-two-lines-renderer.c.

434 {
436  gint x_offset, x_offset_1, x_offset_2, y_offset;
437  PangoLayout *layout_one, *layout_two;
438 
439  /* fetch common information */
440  gd_two_lines_renderer_prepare_layouts (self, cell_area, widget, &layout_one, &layout_two);
441  gd_two_lines_renderer_get_size (cell, widget,
442  layout_one, layout_two,
443  &aligned_area->width, &aligned_area->height,
444  cell_area,
445  &x_offset_1, &x_offset_2, &y_offset);
446 
447  x_offset = MIN (x_offset_1, x_offset_2);
448 
449  aligned_area->x = cell_area->x + x_offset;
450  aligned_area->y = cell_area->y;
451 
452  g_clear_object (&layout_one);
453  g_clear_object (&layout_two);
454 }

+ Here is the caller graph for this function:

static void gd_two_lines_renderer_get_preferred_height ( GtkCellRenderer *  cell,
GtkWidget *  widget,
gint *  minimum_size,
gint *  natural_size 
)
static

Definition at line 416 of file gd-two-lines-renderer.c.

420 {
421  gint min_width;
422 
423  gtk_cell_renderer_get_preferred_width (cell, widget, &min_width, NULL);
425  minimum_size, natural_size);
426 }

+ Here is the caller graph for this function:

static void gd_two_lines_renderer_get_preferred_height_for_width ( GtkCellRenderer *  cell,
GtkWidget *  widget,
gint  width,
gint *  minimum_size,
gint *  natural_size 
)
static

Definition at line 373 of file gd-two-lines-renderer.c.

378 {
380  PangoLayout *layout_one, *layout_two;
381  gint text_height, wrap_width;
382  gint xpad, ypad;
383 
384  gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
385  g_object_get (cell, "wrap-width", &wrap_width, NULL);
386  gd_two_lines_renderer_prepare_layouts (self, NULL, widget, &layout_one, &layout_two);
387 
388  if (wrap_width != -1)
389  wrap_width = MIN (width - 2 * xpad, wrap_width);
390  else
391  wrap_width = width - 2 * xpad;
392 
393  pango_layout_set_width (layout_one, wrap_width);
394  if (layout_two != NULL)
395  pango_layout_set_width (layout_two, wrap_width);
396 
397  gd_two_lines_renderer_get_size (cell, widget,
398  layout_one, layout_two,
399  NULL, &text_height,
400  NULL,
401  NULL, NULL, NULL);
402 
403  text_height += 2 * ypad;
404 
405  if (minimum_size != NULL)
406  *minimum_size = text_height;
407 
408  if (natural_size != NULL)
409  *natural_size = text_height;
410 
411  g_clear_object (&layout_one);
412  g_clear_object (&layout_two);
413 }

+ Here is the caller graph for this function:

static void gd_two_lines_renderer_get_preferred_width ( GtkCellRenderer *  cell,
GtkWidget *  widget,
gint *  minimum_size,
gint *  natural_size 
)
static

Definition at line 305 of file gd-two-lines-renderer.c.

309 {
310  PangoContext *context;
311  PangoFontMetrics *metrics;
312  PangoFontDescription *font_desc;
313  GtkStyleContext *style_context;
314  gint nat_width, min_width;
315  gint xpad, char_width, wrap_width, text_width;
316  gint width_chars, ellipsize_chars;
317 
318  g_object_get (cell,
319  "xpad", &xpad,
320  "width-chars", &width_chars,
321  "wrap-width", &wrap_width,
322  NULL);
323  style_context = gtk_widget_get_style_context (widget);
324  gtk_cell_renderer_get_padding (cell, &xpad, NULL);
325 
326  gd_two_lines_renderer_get_size (cell, widget,
327  NULL, NULL,
328  &text_width, NULL,
329  NULL,
330  NULL, NULL, NULL);
331 
332  /* Fetch the average size of a charachter */
333  context = gtk_widget_get_pango_context (widget);
334  gtk_style_context_save (style_context);
335  gtk_style_context_set_state (style_context, 0);
336  gtk_style_context_get (style_context, 0, "font", &font_desc, NULL);
337  gtk_style_context_restore (style_context);
338  metrics = pango_context_get_metrics (context, font_desc,
339  pango_context_get_language (context));
340 
341  char_width = pango_font_metrics_get_approximate_char_width (metrics);
342 
343  pango_font_metrics_unref (metrics);
344  pango_font_description_free (font_desc);
345 
346  /* enforce minimum width for ellipsized labels at ~3 chars */
347  ellipsize_chars = 3;
348 
349  /* If no width-chars set, minimum for wrapping text will be the wrap-width */
350  if (wrap_width > -1)
351  min_width = xpad * 2 + MIN (text_width, wrap_width);
352  else
353  min_width = xpad * 2 +
354  MIN (text_width,
355  (PANGO_PIXELS (char_width) * MAX (width_chars, ellipsize_chars)));
356 
357  if (width_chars > 0)
358  nat_width = xpad * 2 +
359  MAX ((PANGO_PIXELS (char_width) * width_chars), text_width);
360  else
361  nat_width = xpad * 2 + text_width;
362 
363  nat_width = MAX (nat_width, min_width);
364 
365  if (minimum_size)
366  *minimum_size = min_width;
367 
368  if (natural_size)
369  *natural_size = nat_width;
370 }

+ Here is the caller graph for this function:

static void gd_two_lines_renderer_get_property ( GObject *  object,
guint  property_id,
GValue *  value,
GParamSpec *  pspec 
)
static

Definition at line 503 of file gd-two-lines-renderer.c.

507 {
508  GdTwoLinesRenderer *self = GD_TWO_LINES_RENDERER (object);
509 
510  switch (property_id)
511  {
512  case PROP_TEXT_LINES:
513  g_value_set_int (value, self->priv->text_lines);
514  break;
515  case PROP_LINE_TWO:
516  g_value_set_string (value, self->priv->line_two);
517  break;
518  default:
519  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
520  break;
521  }
522 }

+ Here is the caller graph for this function:

static void gd_two_lines_renderer_get_size ( GtkCellRenderer *  cell,
GtkWidget *  widget,
PangoLayout *  layout_1,
PangoLayout *  layout_2,
gint *  width,
gint *  height,
const GdkRectangle *  cell_area,
gint *  x_offset_1,
gint *  x_offset_2,
gint *  y_offset 
)
static

Definition at line 129 of file gd-two-lines-renderer.c.

139 {
141  gint xpad, ypad;
142  PangoLayout *layout_one, *layout_two;
143  GdkRectangle layout_one_rect, layout_two_rect, layout_union;
144 
145  if (layout_1 == NULL)
146  {
147  gd_two_lines_renderer_prepare_layouts (self, cell_area, widget, &layout_one, &layout_two);
148  }
149  else
150  {
151  layout_one = g_object_ref (layout_1);
152 
153  if (layout_2 != NULL)
154  layout_two = g_object_ref (layout_2);
155  else
156  layout_two = NULL;
157  }
158 
159  gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
160  pango_layout_get_pixel_extents (layout_one, NULL, (PangoRectangle *) &layout_one_rect);
161 
162  if (layout_two != NULL)
163  {
164  pango_layout_get_pixel_extents (layout_two, NULL, (PangoRectangle *) &layout_two_rect);
165 
166  layout_union.width = MAX (layout_one_rect.width, layout_two_rect.width);
167  layout_union.height = layout_one_rect.height + layout_two_rect.height;
168  }
169  else
170  {
171  layout_union = layout_one_rect;
172  }
173 
174  if (cell_area)
175  {
176  gfloat xalign, yalign;
177 
178  gtk_cell_renderer_get_alignment (cell, &xalign, &yalign);
179 
180  layout_union.width = MIN (layout_union.width, cell_area->width - 2 * xpad);
181  layout_union.height = MIN (layout_union.height, cell_area->height - 2 * ypad);
182 
183  if (x_offset_1)
184  {
185  if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
186  *x_offset_1 = (1.0 - xalign) * (cell_area->width - (layout_one_rect.width + (2 * xpad)));
187  else
188  *x_offset_1 = xalign * (cell_area->width - (layout_one_rect.width + (2 * xpad)));
189 
190  *x_offset_1 = MAX (*x_offset_1, 0);
191  }
192  if (x_offset_2)
193  {
194  if (layout_two != NULL)
195  {
196  if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
197  *x_offset_2 = (1.0 - xalign) * (cell_area->width - (layout_two_rect.width + (2 * xpad)));
198  else
199  *x_offset_2 = xalign * (cell_area->width - (layout_two_rect.width + (2 * xpad)));
200 
201  *x_offset_2 = MAX (*x_offset_2, 0);
202  }
203  else
204  {
205  *x_offset_2 = 0;
206  }
207  }
208 
209  if (y_offset)
210  {
211  *y_offset = yalign * (cell_area->height - (layout_union.height + (2 * ypad)));
212  *y_offset = MAX (*y_offset, 0);
213  }
214  }
215  else
216  {
217  if (x_offset_1) *x_offset_1 = 0;
218  if (x_offset_2) *x_offset_2 = 0;
219  if (y_offset) *y_offset = 0;
220  }
221 
222  g_clear_object (&layout_one);
223  g_clear_object (&layout_two);
224 
225  if (height)
226  *height = ypad * 2 + layout_union.height;
227 
228  if (width)
229  *width = xpad * 2 + layout_union.width;
230 }

+ Here is the caller graph for this function:

static void gd_two_lines_renderer_init ( GdTwoLinesRenderer self)
static

Definition at line 569 of file gd-two-lines-renderer.c.

570 {
571  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GD_TYPE_TWO_LINES_RENDERER,
573 }
GtkCellRenderer* gd_two_lines_renderer_new ( void  )

Definition at line 576 of file gd-two-lines-renderer.c.

577 {
578  return g_object_new (GD_TYPE_TWO_LINES_RENDERER, NULL);
579 }

+ Here is the caller graph for this function:

static void gd_two_lines_renderer_prepare_layouts ( GdTwoLinesRenderer self,
const GdkRectangle *  cell_area,
GtkWidget *  widget,
PangoLayout **  layout_one,
PangoLayout **  layout_two 
)
static

Definition at line 82 of file gd-two-lines-renderer.c.

87 {
88  PangoLayout *line_one;
89  PangoLayout *line_two = NULL;
90  gchar *text = NULL;
91 
92  g_object_get (self,
93  "text", &text,
94  NULL);
95 
96  line_one = create_layout_with_attrs (widget, cell_area,
97  self, PANGO_ELLIPSIZE_MIDDLE);
98 
99  if (self->priv->line_two == NULL ||
100  g_strcmp0 (self->priv->line_two, "") == 0)
101  {
102  pango_layout_set_height (line_one, - (self->priv->text_lines));
103 
104  if (text != NULL)
105  pango_layout_set_text (line_one, text, -1);
106  }
107  else
108  {
109  line_two = create_layout_with_attrs (widget, cell_area,
110  self, PANGO_ELLIPSIZE_END);
111 
112  pango_layout_set_height (line_one, - (self->priv->text_lines - 1));
113  pango_layout_set_height (line_two, -1);
114  pango_layout_set_text (line_two, self->priv->line_two, -1);
115 
116  if (text != NULL)
117  pango_layout_set_text (line_one, text, -1);
118  }
119 
120  if (layout_one)
121  *layout_one = line_one;
122  if (layout_two)
123  *layout_two = line_two;
124 
125  g_free (text);
126 }

+ Here is the caller graph for this function:

static void gd_two_lines_renderer_render ( GtkCellRenderer *  cell,
cairo_t *  cr,
GtkWidget *  widget,
const GdkRectangle *  background_area,
const GdkRectangle *  cell_area,
GtkCellRendererState  flags 
)
static

Definition at line 233 of file gd-two-lines-renderer.c.

239 {
241  GtkStyleContext *context;
242  gint line_one_height;
243  GtkStateFlags state;
244  GdkRectangle area, render_area = *cell_area;
245  gint xpad, ypad, x_offset_1, x_offset_2, y_offset;
246  PangoLayout *layout_one, *layout_two;
247  PangoRectangle layout_rect;
248 
249  /* fetch common information */
250  context = gtk_widget_get_style_context (widget);
251  gd_two_lines_renderer_prepare_layouts (self, cell_area, widget, &layout_one, &layout_two);
252  gd_two_lines_renderer_get_size (cell, widget,
253  layout_one, layout_two,
254  NULL, NULL,
255  cell_area,
256  &x_offset_1, &x_offset_2, &y_offset);
257  gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
258 
259  area = *cell_area;
260  area.x += xpad;
261  area.y += ypad;
262 
263  /* now render the first layout */
264  pango_layout_get_pixel_extents (layout_one, NULL, &layout_rect);
265 
266  render_area = area;
267  render_area.x += x_offset_1 - layout_rect.x;
268 
269  gtk_render_layout (context, cr,
270  render_area.x,
271  render_area.y,
272  layout_one);
273 
274  /* render the second layout */
275  if (layout_two != NULL)
276  {
277  pango_layout_get_pixel_size (layout_one,
278  NULL, &line_one_height);
279 
280  gtk_style_context_save (context);
281  gtk_style_context_add_class (context, "dim-label");
282 
283  state = gtk_cell_renderer_get_state (cell, widget, flags);
284  gtk_style_context_set_state (context, state);
285 
286  pango_layout_get_pixel_extents (layout_two, NULL, &layout_rect);
287 
288  render_area = area;
289  render_area.x += x_offset_2 - layout_rect.x;
290  render_area.y += line_one_height;
291 
292  gtk_render_layout (context, cr,
293  render_area.x,
294  render_area.y,
295  layout_two);
296 
297  gtk_style_context_restore (context);
298  }
299 
300  g_clear_object (&layout_one);
301  g_clear_object (&layout_two);
302 }

+ Here is the caller graph for this function:

static void gd_two_lines_renderer_set_line_two ( GdTwoLinesRenderer self,
const gchar *  line_two 
)
static

Definition at line 457 of file gd-two-lines-renderer.c.

459 {
460  if (g_strcmp0 (self->priv->line_two, line_two) == 0)
461  return;
462 
463  g_free (self->priv->line_two);
464  self->priv->line_two = g_strdup (line_two);
465 
466  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_LINE_TWO]);
467 }

+ Here is the caller graph for this function:

static void gd_two_lines_renderer_set_property ( GObject *  object,
guint  property_id,
const GValue *  value,
GParamSpec *  pspec 
)
static

Definition at line 481 of file gd-two-lines-renderer.c.

485 {
486  GdTwoLinesRenderer *self = GD_TWO_LINES_RENDERER (object);
487 
488  switch (property_id)
489  {
490  case PROP_TEXT_LINES:
491  gd_two_lines_renderer_set_text_lines (self, g_value_get_int (value));
492  break;
493  case PROP_LINE_TWO:
494  gd_two_lines_renderer_set_line_two (self, g_value_get_string (value));
495  break;
496  default:
497  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
498  break;
499  }
500 }

+ Here is the caller graph for this function:

static void gd_two_lines_renderer_set_text_lines ( GdTwoLinesRenderer self,
gint  text_lines 
)
static

Definition at line 470 of file gd-two-lines-renderer.c.

472 {
473  if (self->priv->text_lines == text_lines)
474  return;
475 
476  self->priv->text_lines = text_lines;
477  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TEXT_LINES]);
478 }

+ Here is the caller graph for this function:

Variable Documentation

GParamSpec* properties[NUM_PROPERTIES] = { NULL, }
static

Definition at line 38 of file gd-two-lines-renderer.c.