1 /* LIBGTK - The GTK Library
2 * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
4 * This library is free software: you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 3 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see
16 * <http://www.gnu.org/licenses/>.
20 #include "claws-features.h"
28 #include "gtkshruler.h"
31 #define ROUND(x) ((int) ((x) + 0.5))
36 * @short_description: Definitions of useful #GParamFlags.
38 * Definitions of useful #GParamFlags.
43 * GTK_PARAM_STATIC_STRINGS:
47 #define GTK_PARAM_STATIC_STRINGS (G_PARAM_STATIC_NAME | \
48 G_PARAM_STATIC_NICK | \
56 #define GTK_PARAM_READABLE (G_PARAM_READABLE | \
57 GTK_PARAM_STATIC_STRINGS)
64 #define GTK_PARAM_WRITABLE (G_PARAM_WRITABLE | \
65 GTK_PARAM_STATIC_STRINGS)
68 * GTK_PARAM_READWRITE:
72 #define GTK_PARAM_READWRITE (G_PARAM_READWRITE | \
73 GTK_PARAM_STATIC_STRINGS)
79 * @short_description: A ruler widget with configurable unit and orientation.
81 * A ruler widget with configurable unit and orientation.
85 #define DEFAULT_RULER_FONT_SCALE PANGO_SCALE_SMALL
86 #define MINIMUM_INCR 5
101 /* All distances below are in 1/72nd's of an inch. (According to
102 * Adobe that's a point, but points are really 1/72.27 in.)
106 GtkOrientation orientation;
113 GdkWindow *input_window;
114 cairo_surface_t *backing_store;
122 #define GTK_SHRULER_GET_PRIVATE(ruler) \
123 G_TYPE_INSTANCE_GET_PRIVATE (ruler, GTK_TYPE_SHRULER, GtkSHRulerPrivate)
128 const gdouble ruler_scale[16];
129 const gint subdivide[3];
132 { 1, 2, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000, 25000, 50000, 100000 },
137 static void gtk_shruler_dispose (GObject *object);
138 static void gtk_shruler_set_property (GObject *object,
142 static void gtk_shruler_get_property (GObject *object,
147 static void gtk_shruler_realize (GtkWidget *widget);
148 static void gtk_shruler_unrealize (GtkWidget *widget);
149 static void gtk_shruler_map (GtkWidget *widget);
150 static void gtk_shruler_unmap (GtkWidget *widget);
151 static void gtk_shruler_size_allocate (GtkWidget *widget,
152 GtkAllocation *allocation);
153 #if GTK_CHECK_VERSION(3, 0, 0)
154 static void gtk_shruler_get_preferred_height (GtkWidget *widget,
155 gint *minimal_height,
156 gint *natural_height);
157 static void gtk_shruler_get_preferred_width (GtkWidget *widget,
159 gint *natural_width);
161 static void gtk_shruler_size_request (GtkWidget *widget,
162 GtkRequisition *requisition);
163 static void gtk_shruler_style_set (GtkWidget *widget,
164 GtkStyle *prev_style);
165 static gboolean gtk_shruler_motion_notify (GtkWidget *widget,
166 GdkEventMotion *event);
167 #if !GTK_CHECK_VERSION(3, 0, 0)
168 static gboolean gtk_shruler_expose (GtkWidget *widget,
169 GdkEventExpose *event);
171 static gboolean gtk_shruler_expose (GtkWidget *widget,
175 static void gtk_shruler_draw_ticks (GtkSHRuler *ruler);
176 static void gtk_shruler_make_pixmap (GtkSHRuler *ruler);
178 static PangoLayout * gtk_shruler_get_layout (GtkWidget *widget,
181 #if !GLIB_CHECK_VERSION(2, 58, 0)
182 G_DEFINE_TYPE (GtkSHRuler, gtk_shruler, GTK_TYPE_WIDGET)
184 G_DEFINE_TYPE_WITH_CODE (GtkSHRuler, gtk_shruler, GTK_TYPE_WIDGET,
185 G_ADD_PRIVATE(GtkSHRuler))
188 #define parent_class gtk_shruler_parent_class
192 gtk_shruler_class_init (GtkSHRulerClass *klass)
194 GObjectClass *object_class = G_OBJECT_CLASS (klass);
195 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
197 object_class->dispose = gtk_shruler_dispose;
198 object_class->set_property = gtk_shruler_set_property;
199 object_class->get_property = gtk_shruler_get_property;
201 widget_class->realize = gtk_shruler_realize;
202 widget_class->unrealize = gtk_shruler_unrealize;
203 widget_class->map = gtk_shruler_map;
204 widget_class->unmap = gtk_shruler_unmap;
205 widget_class->size_allocate = gtk_shruler_size_allocate;
206 #if !GTK_CHECK_VERSION(3, 0, 0)
207 widget_class->size_request = gtk_shruler_size_request;
209 widget_class->get_preferred_width = gtk_shruler_get_preferred_width;
210 widget_class->get_preferred_height = gtk_shruler_get_preferred_height;
212 widget_class->style_set = gtk_shruler_style_set;
213 widget_class->motion_notify_event = gtk_shruler_motion_notify;
214 #if !GTK_CHECK_VERSION(3, 0, 0)
215 widget_class->expose_event = gtk_shruler_expose;
217 widget_class->draw = gtk_shruler_expose;
220 #if !GLIB_CHECK_VERSION(2, 58, 0)
221 g_type_class_add_private (object_class, sizeof (GtkSHRulerPrivate));
224 g_object_class_install_property (object_class,
226 g_param_spec_enum ("orientation",
228 "The orientation of the ruler",
229 GTK_TYPE_ORIENTATION,
230 GTK_ORIENTATION_HORIZONTAL,
231 GTK_PARAM_READWRITE));
233 g_object_class_install_property (object_class,
235 gtk_param_spec_unit ("unit",
240 GTK_PARAM_READWRITE));
242 g_object_class_install_property (object_class,
244 g_param_spec_double ("lower",
246 "Lower limit of ruler",
250 GTK_PARAM_READWRITE));
252 g_object_class_install_property (object_class,
254 g_param_spec_double ("upper",
256 "Upper limit of ruler",
260 GTK_PARAM_READWRITE));
262 g_object_class_install_property (object_class,
264 g_param_spec_double ("position",
266 "Position of mark on the ruler",
270 GTK_PARAM_READWRITE));
272 g_object_class_install_property (object_class,
274 g_param_spec_double ("max-size",
276 "Maximum size of the ruler",
280 GTK_PARAM_READWRITE));
282 gtk_widget_class_install_style_property (widget_class,
283 g_param_spec_double ("font-scale",
287 DEFAULT_RULER_FONT_SCALE,
288 GTK_PARAM_READABLE));
292 gtk_shruler_init (GtkSHRuler *ruler)
294 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (ruler);
296 gtk_widget_set_has_window (GTK_WIDGET (ruler), FALSE);
298 priv->orientation = GTK_ORIENTATION_HORIZONTAL;
299 #if !GTK_CHECK_VERSION(3, 0, 0)
300 priv->unit = GTK_PIXELS;
308 priv->backing_store = NULL;
309 priv->font_scale = DEFAULT_RULER_FONT_SCALE;
313 gtk_shruler_dispose (GObject *object)
315 G_OBJECT_CLASS (parent_class)->dispose (object);
319 gtk_shruler_set_property (GObject *object,
324 GtkSHRuler *ruler = GTK_SHRULER (object);
325 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (ruler);
329 case PROP_ORIENTATION:
330 priv->orientation = g_value_get_enum (value);
331 gtk_widget_queue_resize (GTK_WIDGET (ruler));
335 gtk_shruler_set_unit (ruler, g_value_get_int (value));
339 gtk_shruler_set_range (ruler,
340 g_value_get_double (value),
345 gtk_shruler_set_range (ruler,
347 g_value_get_double (value),
352 gtk_shruler_set_position (ruler, g_value_get_double (value));
356 gtk_shruler_set_range (ruler,
359 g_value_get_double (value));
363 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
369 gtk_shruler_get_property (GObject *object,
374 GtkSHRuler *ruler = GTK_SHRULER (object);
375 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (ruler);
379 case PROP_ORIENTATION:
380 g_value_set_enum (value, priv->orientation);
384 g_value_set_int (value, priv->unit);
388 g_value_set_double (value, priv->lower);
392 g_value_set_double (value, priv->upper);
396 g_value_set_double (value, priv->position);
400 g_value_set_double (value, priv->max_size);
404 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
411 * @orientation: the ruler's orientation.
413 * Creates a new ruler.
415 * Return value: a new #GtkSHRuler widget.
420 gtk_shruler_new (GtkOrientation orientation)
422 return g_object_new (GTK_TYPE_SHRULER,
423 "orientation", orientation,
428 gtk_shruler_update_position (GtkSHRuler *ruler,
432 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (ruler);
433 GtkAllocation allocation;
437 gtk_widget_get_allocation (GTK_WIDGET (ruler), &allocation);
438 gtk_shruler_get_range (ruler, &lower, &upper, NULL);
440 if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
442 gtk_shruler_set_position (ruler,
444 (upper - lower) * x / allocation.width);
448 gtk_shruler_set_position (ruler,
450 (upper - lower) * y / allocation.height);
455 * gtk_shruler_set_unit:
456 * @ruler: a #GtkSHRuler
457 * @unit: the #GtkCMUnit to set the ruler to
459 * This sets the unit of the ruler.
464 gtk_shruler_set_unit (GtkSHRuler *ruler,
467 GtkSHRulerPrivate *priv;
469 g_return_if_fail (GTK_IS_SHRULER (ruler));
471 priv = GTK_SHRULER_GET_PRIVATE (ruler);
473 if (priv->unit != unit)
476 g_object_notify (G_OBJECT (ruler), "unit");
478 gtk_widget_queue_draw (GTK_WIDGET (ruler));
483 * gtk_shruler_get_unit:
484 * @ruler: a #GtkSHRuler
486 * Return value: the unit currently used in the @ruler widget.
491 gtk_shruler_get_unit (GtkSHRuler *ruler)
493 g_return_val_if_fail (GTK_IS_SHRULER (ruler), 0);
495 return GTK_SHRULER_GET_PRIVATE (ruler)->unit;
499 * gtk_shruler_set_position:
500 * @ruler: a #GtkSHRuler
501 * @position: the position to set the ruler to
503 * This sets the position of the ruler.
508 gtk_shruler_set_position (GtkSHRuler *ruler,
511 GtkSHRulerPrivate *priv;
513 g_return_if_fail (GTK_IS_SHRULER (ruler));
515 priv = GTK_SHRULER_GET_PRIVATE (ruler);
517 if (priv->position != position)
519 priv->position = position;
520 g_object_notify (G_OBJECT (ruler), "position");
525 * gtk_shruler_get_position:
526 * @ruler: a #GtkSHRuler
528 * Return value: the current position of the @ruler widget.
533 gtk_shruler_get_position (GtkSHRuler *ruler)
535 g_return_val_if_fail (GTK_IS_SHRULER (ruler), 0.0);
537 return GTK_SHRULER_GET_PRIVATE (ruler)->position;
541 * gtk_shruler_set_range:
542 * @ruler: a #GtkSHRuler
543 * @lower: the lower limit of the ruler
544 * @upper: the upper limit of the ruler
545 * @max_size: the maximum size of the ruler used when calculating the space to
548 * This sets the range of the ruler.
553 gtk_shruler_set_range (GtkSHRuler *ruler,
558 GtkSHRulerPrivate *priv;
560 g_return_if_fail (GTK_IS_SHRULER (ruler));
562 priv = GTK_SHRULER_GET_PRIVATE (ruler);
564 g_object_freeze_notify (G_OBJECT (ruler));
565 if (priv->lower != lower)
568 g_object_notify (G_OBJECT (ruler), "lower");
570 if (priv->upper != upper)
573 g_object_notify (G_OBJECT (ruler), "upper");
575 if (priv->max_size != max_size)
577 priv->max_size = max_size;
578 g_object_notify (G_OBJECT (ruler), "max-size");
580 g_object_thaw_notify (G_OBJECT (ruler));
582 gtk_widget_queue_draw (GTK_WIDGET (ruler));
586 * gtk_shruler_get_range:
587 * @ruler: a #GtkSHRuler
588 * @lower: location to store lower limit of the ruler, or %NULL
589 * @upper: location to store upper limit of the ruler, or %NULL
590 * @max_size: location to store the maximum size of the ruler used when
591 * calculating the space to leave for the text, or %NULL.
593 * Retrieves values indicating the range and current position of a #GtkSHRuler.
594 * See gtk_shruler_set_range().
599 gtk_shruler_get_range (GtkSHRuler *ruler,
604 GtkSHRulerPrivate *priv;
606 g_return_if_fail (GTK_IS_SHRULER (ruler));
608 priv = GTK_SHRULER_GET_PRIVATE (ruler);
611 *lower = priv->lower;
613 *upper = priv->upper;
615 *max_size = priv->max_size;
619 gtk_shruler_realize (GtkWidget *widget)
621 GtkSHRuler *ruler = GTK_SHRULER (widget);
622 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (ruler);
623 GtkAllocation allocation;
624 GdkWindowAttr attributes;
625 gint attributes_mask;
627 GTK_WIDGET_CLASS (gtk_shruler_parent_class)->realize (widget);
629 gtk_widget_get_allocation (widget, &allocation);
631 attributes.window_type = GDK_WINDOW_CHILD;
632 attributes.x = allocation.x;
633 attributes.y = allocation.y;
634 attributes.width = allocation.width;
635 attributes.height = allocation.height;
636 attributes.wclass = GDK_INPUT_ONLY;
637 attributes.event_mask = (gtk_widget_get_events (widget) |
639 GDK_POINTER_MOTION_MASK |
640 GDK_POINTER_MOTION_HINT_MASK);
642 attributes_mask = GDK_WA_X | GDK_WA_Y;
644 priv->input_window = gdk_window_new (gtk_widget_get_window (widget),
645 &attributes, attributes_mask);
646 gdk_window_set_user_data (priv->input_window, ruler);
648 gtk_shruler_make_pixmap (ruler);
652 gtk_shruler_unrealize (GtkWidget *widget)
654 GtkSHRuler *ruler = GTK_SHRULER (widget);
655 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (ruler);
657 if (priv->backing_store)
659 cairo_surface_destroy (priv->backing_store);
660 priv->backing_store = NULL;
665 g_object_unref (priv->layout);
669 if (priv->input_window)
671 gdk_window_destroy (priv->input_window);
672 priv->input_window = NULL;
675 GTK_WIDGET_CLASS (gtk_shruler_parent_class)->unrealize (widget);
679 gtk_shruler_map (GtkWidget *widget)
681 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (widget);
683 GTK_WIDGET_CLASS (parent_class)->map (widget);
685 if (priv->input_window)
686 gdk_window_show (priv->input_window);
690 gtk_shruler_unmap (GtkWidget *widget)
692 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (widget);
694 if (priv->input_window)
695 gdk_window_hide (priv->input_window);
697 GTK_WIDGET_CLASS (parent_class)->unmap (widget);
701 gtk_shruler_size_allocate (GtkWidget *widget,
702 GtkAllocation *allocation)
704 GtkSHRuler *ruler = GTK_SHRULER (widget);
705 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (ruler);
707 gtk_widget_set_allocation (widget, allocation);
709 if (gtk_widget_get_realized (widget))
711 gdk_window_move_resize (priv->input_window,
712 allocation->x, allocation->y,
713 allocation->width, allocation->height);
715 gtk_shruler_make_pixmap (ruler);
719 #if GTK_CHECK_VERSION(3, 0, 0)
721 gtk_shruler_get_preferred_width (GtkWidget *widget,
725 GtkRequisition requisition;
727 gtk_shruler_size_request (widget, &requisition);
729 *minimal_width = *natural_width = requisition.width;
733 gtk_shruler_get_preferred_height (GtkWidget *widget,
734 gint *minimal_height,
735 gint *natural_height)
737 GtkRequisition requisition;
739 gtk_shruler_size_request (widget, &requisition);
741 *minimal_height = *natural_height = requisition.height;
746 gtk_shruler_size_request (GtkWidget *widget,
747 GtkRequisition *requisition)
749 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (widget);
750 GtkStyle *style = gtk_widget_get_style (widget);
752 PangoRectangle ink_rect;
755 layout = gtk_shruler_get_layout (widget, "0123456789");
756 pango_layout_get_pixel_extents (layout, &ink_rect, NULL);
758 size = 2 + ink_rect.height * 1.7;
760 if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
762 requisition->width = style->xthickness * 2 + 1;
763 requisition->height = style->ythickness * 2 + size;
767 requisition->width = style->xthickness * 2 + size;
768 requisition->height = style->ythickness * 2 + 1;
773 gtk_shruler_style_set (GtkWidget *widget,
774 GtkStyle *prev_style)
776 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (widget);
778 GTK_WIDGET_CLASS (gtk_shruler_parent_class)->style_set (widget, prev_style);
780 gtk_widget_style_get (widget,
781 "font-scale", &priv->font_scale,
786 g_object_unref (priv->layout);
792 gtk_shruler_motion_notify (GtkWidget *widget,
793 GdkEventMotion *event)
795 GtkSHRuler *ruler = GTK_SHRULER (widget);
797 gdk_event_request_motions (event);
799 gtk_shruler_update_position (ruler, event->x, event->y);
804 #if !GTK_CHECK_VERSION(3, 0, 0)
806 gtk_shruler_expose (GtkWidget *widget,
807 GdkEventExpose *event)
810 gtk_shruler_expose (GtkWidget *widget,
814 if (gtk_widget_is_drawable (widget))
816 GtkSHRuler *ruler = GTK_SHRULER (widget);
817 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (ruler);
818 GtkAllocation allocation;
819 #if !GTK_CHECK_VERSION(3, 0, 0)
823 gtk_shruler_draw_ticks (ruler);
825 #if !GTK_CHECK_VERSION(3, 0, 0)
826 cr = gdk_cairo_create (gtk_widget_get_window (widget));
827 gdk_cairo_region (cr, event->region);
831 gtk_widget_get_allocation (widget, &allocation);
832 #if !GTK_CHECK_VERSION(3, 0, 0)
833 cairo_translate (cr, allocation.x, allocation.y);
836 cairo_set_source_surface (cr, priv->backing_store, 0, 0);
839 #if !GTK_CHECK_VERSION(3, 0, 0)
848 gtk_shruler_draw_ticks (GtkSHRuler *ruler)
850 GtkWidget *widget = GTK_WIDGET (ruler);
851 GtkStyle *style = gtk_widget_get_style (widget);
852 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (ruler);
853 GtkStateType state = gtk_widget_get_state (widget);
854 GtkAllocation allocation;
861 gdouble lower, upper; /* Upper and lower limits, in ruler units */
862 gdouble increment; /* Number of pixels per unit */
863 gint scale; /* Number of units per major unit */
864 gdouble start, end, cur;
873 PangoRectangle logical_rect, ink_rect;
875 if (! gtk_widget_is_drawable (widget))
878 gtk_widget_get_allocation (widget, &allocation);
880 xthickness = style->xthickness;
881 ythickness = style->ythickness;
883 layout = gtk_shruler_get_layout (widget, "0123456789");
884 pango_layout_get_extents (layout, &ink_rect, &logical_rect);
886 digit_height = PANGO_PIXELS (ink_rect.height) + 2;
887 digit_offset = ink_rect.y;
889 if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
891 width = allocation.width;
892 height = allocation.height - ythickness * 2;
896 width = allocation.height;
897 height = allocation.width - ythickness * 2;
900 cr = cairo_create (priv->backing_store);
901 gdk_cairo_set_source_color (cr, &style->bg[state]);
905 gdk_cairo_set_source_color (cr, &style->fg[state]);
907 gtk_shruler_get_range (ruler, &lower, &upper, &max_size);
909 if ((upper - lower) == 0)
912 increment = (gdouble) width / (upper - lower);
914 /* determine the scale
915 * use the maximum extents of the ruler to determine the largest
916 * possible number to be displayed. Calculate the height in pixels
917 * of this displayed text. Use this height to find a scale which
918 * leaves sufficient room for drawing the ruler.
920 * We calculate the text size as for the vruler instead of
921 * actually measuring the text width, so that the result for the
922 * scale looks consistent with an accompanying vruler.
924 scale = ceil (max_size);
925 g_snprintf (unit_str, sizeof (unit_str), "%d", scale);
926 text_size = strlen (unit_str) * digit_height + 1;
928 for (scale = 0; scale < G_N_ELEMENTS (ruler_metric.ruler_scale); scale++)
929 if (ruler_metric.ruler_scale[scale] * fabs (increment) > 2 * text_size)
932 if (scale == G_N_ELEMENTS (ruler_metric.ruler_scale))
933 scale = G_N_ELEMENTS (ruler_metric.ruler_scale) - 1;
935 unit = gtk_shruler_get_unit (ruler);
937 /* drawing starts here */
939 for (i = G_N_ELEMENTS (ruler_metric.subdivide) - 1; i >= 0; i--)
943 /* hack to get proper subdivisions at full pixels */
944 if (unit == CM_UNIT_PIXEL && scale == 1 && i == 1)
947 subd_incr = ((gdouble) ruler_metric.ruler_scale[scale] /
948 (gdouble) ruler_metric.subdivide[i]);
950 if (subd_incr * fabs (increment) <= MINIMUM_INCR)
953 /* don't subdivide pixels */
954 if (unit == CM_UNIT_PIXEL && subd_incr < 1.0)
959 start = floor (lower / subd_incr) * subd_incr;
960 end = ceil (upper / subd_incr) * subd_incr;
964 start = floor (upper / subd_incr) * subd_incr;
965 end = ceil (lower / subd_incr) * subd_incr;
968 for (cur = start; cur <= end; cur += subd_incr)
970 if (((int)cur) % 10 == 0)
971 length = height * 2 / 3;
972 else if (((int)cur) % 5 == 0)
977 pos = ROUND ((cur - lower) * increment);
979 if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
982 pos, height + ythickness - length,
988 height + xthickness - length, pos,
993 if (i == 0 && ((int)cur) % 10 == 0)
995 g_snprintf (unit_str, sizeof (unit_str), "%d", (int) cur);
997 if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
999 pango_layout_set_text (layout, unit_str, -1);
1000 pango_layout_get_extents (layout, &logical_rect, NULL);
1004 ythickness + PANGO_PIXELS (logical_rect.y - digit_offset));
1005 pango_cairo_show_layout (cr, layout);
1011 for (j = 0; j < (int) strlen (unit_str); j++)
1013 pango_layout_set_text (layout, unit_str + j, 1);
1014 pango_layout_get_extents (layout, NULL, &logical_rect);
1018 pos + digit_height * j + 2 + PANGO_PIXELS (logical_rect.y - digit_offset));
1019 pango_cairo_show_layout (cr, layout);
1032 gtk_shruler_make_pixmap (GtkSHRuler *ruler)
1034 GtkWidget *widget = GTK_WIDGET (ruler);
1035 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (ruler);
1036 GtkAllocation allocation;
1038 gtk_widget_get_allocation (widget, &allocation);
1040 if (priv->backing_store)
1041 cairo_surface_destroy (priv->backing_store);
1043 priv->backing_store =
1044 gdk_window_create_similar_surface (gtk_widget_get_window (widget),
1045 CAIRO_CONTENT_COLOR,
1051 static PangoLayout *
1052 gtk_shruler_create_layout (GtkWidget *widget,
1055 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (widget);
1056 PangoLayout *layout;
1057 PangoAttrList *attrs;
1058 PangoAttribute *attr;
1060 layout = gtk_widget_create_pango_layout (widget, text);
1062 attrs = pango_attr_list_new ();
1064 attr = pango_attr_scale_new (priv->font_scale);
1065 attr->start_index = 0;
1066 attr->end_index = -1;
1067 pango_attr_list_insert (attrs, attr);
1069 pango_layout_set_attributes (layout, attrs);
1070 pango_attr_list_unref (attrs);
1075 static PangoLayout *
1076 gtk_shruler_get_layout (GtkWidget *widget,
1079 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (widget);
1083 pango_layout_set_text (priv->layout, text, -1);
1084 return priv->layout;
1087 priv->layout = gtk_shruler_create_layout (widget, text);
1089 return priv->layout;