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,
182 G_DEFINE_TYPE (GtkSHRuler, gtk_shruler, GTK_TYPE_WIDGET)
184 #define parent_class gtk_shruler_parent_class
188 gtk_shruler_class_init (GtkSHRulerClass *klass)
190 GObjectClass *object_class = G_OBJECT_CLASS (klass);
191 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
193 object_class->dispose = gtk_shruler_dispose;
194 object_class->set_property = gtk_shruler_set_property;
195 object_class->get_property = gtk_shruler_get_property;
197 widget_class->realize = gtk_shruler_realize;
198 widget_class->unrealize = gtk_shruler_unrealize;
199 widget_class->map = gtk_shruler_map;
200 widget_class->unmap = gtk_shruler_unmap;
201 widget_class->size_allocate = gtk_shruler_size_allocate;
202 #if !GTK_CHECK_VERSION(3, 0, 0)
203 widget_class->size_request = gtk_shruler_size_request;
205 widget_class->get_preferred_width = gtk_shruler_get_preferred_width;
206 widget_class->get_preferred_height = gtk_shruler_get_preferred_height;
208 widget_class->style_set = gtk_shruler_style_set;
209 widget_class->motion_notify_event = gtk_shruler_motion_notify;
210 #if !GTK_CHECK_VERSION(3, 0, 0)
211 widget_class->expose_event = gtk_shruler_expose;
213 widget_class->draw = gtk_shruler_expose;
216 g_type_class_add_private (object_class, sizeof (GtkSHRulerPrivate));
218 g_object_class_install_property (object_class,
220 g_param_spec_enum ("orientation",
222 "The orientation of the ruler",
223 GTK_TYPE_ORIENTATION,
224 GTK_ORIENTATION_HORIZONTAL,
225 GTK_PARAM_READWRITE));
227 g_object_class_install_property (object_class,
229 gtk_param_spec_unit ("unit",
234 GTK_PARAM_READWRITE));
236 g_object_class_install_property (object_class,
238 g_param_spec_double ("lower",
240 "Lower limit of ruler",
244 GTK_PARAM_READWRITE));
246 g_object_class_install_property (object_class,
248 g_param_spec_double ("upper",
250 "Upper limit of ruler",
254 GTK_PARAM_READWRITE));
256 g_object_class_install_property (object_class,
258 g_param_spec_double ("position",
260 "Position of mark on the ruler",
264 GTK_PARAM_READWRITE));
266 g_object_class_install_property (object_class,
268 g_param_spec_double ("max-size",
270 "Maximum size of the ruler",
274 GTK_PARAM_READWRITE));
276 gtk_widget_class_install_style_property (widget_class,
277 g_param_spec_double ("font-scale",
281 DEFAULT_RULER_FONT_SCALE,
282 GTK_PARAM_READABLE));
286 gtk_shruler_init (GtkSHRuler *ruler)
288 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (ruler);
290 gtkut_widget_set_has_window (GTK_WIDGET (ruler), FALSE);
292 priv->orientation = GTK_ORIENTATION_HORIZONTAL;
293 #if !GTK_CHECK_VERSION(3, 0, 0)
294 priv->unit = GTK_PIXELS;
302 priv->backing_store = NULL;
303 priv->font_scale = DEFAULT_RULER_FONT_SCALE;
307 gtk_shruler_dispose (GObject *object)
309 G_OBJECT_CLASS (parent_class)->dispose (object);
313 gtk_shruler_set_property (GObject *object,
318 GtkSHRuler *ruler = GTK_SHRULER (object);
319 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (ruler);
323 case PROP_ORIENTATION:
324 priv->orientation = g_value_get_enum (value);
325 gtk_widget_queue_resize (GTK_WIDGET (ruler));
329 gtk_shruler_set_unit (ruler, g_value_get_int (value));
333 gtk_shruler_set_range (ruler,
334 g_value_get_double (value),
339 gtk_shruler_set_range (ruler,
341 g_value_get_double (value),
346 gtk_shruler_set_position (ruler, g_value_get_double (value));
350 gtk_shruler_set_range (ruler,
353 g_value_get_double (value));
357 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
363 gtk_shruler_get_property (GObject *object,
368 GtkSHRuler *ruler = GTK_SHRULER (object);
369 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (ruler);
373 case PROP_ORIENTATION:
374 g_value_set_enum (value, priv->orientation);
378 g_value_set_int (value, priv->unit);
382 g_value_set_double (value, priv->lower);
386 g_value_set_double (value, priv->upper);
390 g_value_set_double (value, priv->position);
394 g_value_set_double (value, priv->max_size);
398 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
405 * @orientation: the ruler's orientation.
407 * Creates a new ruler.
409 * Return value: a new #GtkSHRuler widget.
414 gtk_shruler_new (GtkOrientation orientation)
416 return g_object_new (GTK_TYPE_SHRULER,
417 "orientation", orientation,
422 gtk_shruler_update_position (GtkSHRuler *ruler,
426 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (ruler);
427 GtkAllocation allocation;
431 gtk_widget_get_allocation (GTK_WIDGET (ruler), &allocation);
432 gtk_shruler_get_range (ruler, &lower, &upper, NULL);
434 if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
436 gtk_shruler_set_position (ruler,
438 (upper - lower) * x / allocation.width);
442 gtk_shruler_set_position (ruler,
444 (upper - lower) * y / allocation.height);
449 * gtk_shruler_set_unit:
450 * @ruler: a #GtkSHRuler
451 * @unit: the #GtkCMUnit to set the ruler to
453 * This sets the unit of the ruler.
458 gtk_shruler_set_unit (GtkSHRuler *ruler,
461 GtkSHRulerPrivate *priv;
463 g_return_if_fail (GTK_IS_SHRULER (ruler));
465 priv = GTK_SHRULER_GET_PRIVATE (ruler);
467 if (priv->unit != unit)
470 g_object_notify (G_OBJECT (ruler), "unit");
472 gtk_widget_queue_draw (GTK_WIDGET (ruler));
477 * gtk_shruler_get_unit:
478 * @ruler: a #GtkSHRuler
480 * Return value: the unit currently used in the @ruler widget.
485 gtk_shruler_get_unit (GtkSHRuler *ruler)
487 g_return_val_if_fail (GTK_IS_SHRULER (ruler), 0);
489 return GTK_SHRULER_GET_PRIVATE (ruler)->unit;
493 * gtk_shruler_set_position:
494 * @ruler: a #GtkSHRuler
495 * @position: the position to set the ruler to
497 * This sets the position of the ruler.
502 gtk_shruler_set_position (GtkSHRuler *ruler,
505 GtkSHRulerPrivate *priv;
507 g_return_if_fail (GTK_IS_SHRULER (ruler));
509 priv = GTK_SHRULER_GET_PRIVATE (ruler);
511 if (priv->position != position)
513 priv->position = position;
514 g_object_notify (G_OBJECT (ruler), "position");
519 * gtk_shruler_get_position:
520 * @ruler: a #GtkSHRuler
522 * Return value: the current position of the @ruler widget.
527 gtk_shruler_get_position (GtkSHRuler *ruler)
529 g_return_val_if_fail (GTK_IS_SHRULER (ruler), 0.0);
531 return GTK_SHRULER_GET_PRIVATE (ruler)->position;
535 * gtk_shruler_set_range:
536 * @ruler: a #GtkSHRuler
537 * @lower: the lower limit of the ruler
538 * @upper: the upper limit of the ruler
539 * @max_size: the maximum size of the ruler used when calculating the space to
542 * This sets the range of the ruler.
547 gtk_shruler_set_range (GtkSHRuler *ruler,
552 GtkSHRulerPrivate *priv;
554 g_return_if_fail (GTK_IS_SHRULER (ruler));
556 priv = GTK_SHRULER_GET_PRIVATE (ruler);
558 g_object_freeze_notify (G_OBJECT (ruler));
559 if (priv->lower != lower)
562 g_object_notify (G_OBJECT (ruler), "lower");
564 if (priv->upper != upper)
567 g_object_notify (G_OBJECT (ruler), "upper");
569 if (priv->max_size != max_size)
571 priv->max_size = max_size;
572 g_object_notify (G_OBJECT (ruler), "max-size");
574 g_object_thaw_notify (G_OBJECT (ruler));
576 gtk_widget_queue_draw (GTK_WIDGET (ruler));
580 * gtk_shruler_get_range:
581 * @ruler: a #GtkSHRuler
582 * @lower: location to store lower limit of the ruler, or %NULL
583 * @upper: location to store upper limit of the ruler, or %NULL
584 * @max_size: location to store the maximum size of the ruler used when
585 * calculating the space to leave for the text, or %NULL.
587 * Retrieves values indicating the range and current position of a #GtkSHRuler.
588 * See gtk_shruler_set_range().
593 gtk_shruler_get_range (GtkSHRuler *ruler,
598 GtkSHRulerPrivate *priv;
600 g_return_if_fail (GTK_IS_SHRULER (ruler));
602 priv = GTK_SHRULER_GET_PRIVATE (ruler);
605 *lower = priv->lower;
607 *upper = priv->upper;
609 *max_size = priv->max_size;
613 gtk_shruler_realize (GtkWidget *widget)
615 GtkSHRuler *ruler = GTK_SHRULER (widget);
616 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (ruler);
617 GtkAllocation allocation;
618 GdkWindowAttr attributes;
619 gint attributes_mask;
621 GTK_WIDGET_CLASS (gtk_shruler_parent_class)->realize (widget);
623 gtk_widget_get_allocation (widget, &allocation);
625 attributes.window_type = GDK_WINDOW_CHILD;
626 attributes.x = allocation.x;
627 attributes.y = allocation.y;
628 attributes.width = allocation.width;
629 attributes.height = allocation.height;
630 attributes.wclass = GDK_INPUT_ONLY;
631 attributes.event_mask = (gtk_widget_get_events (widget) |
633 GDK_POINTER_MOTION_MASK |
634 GDK_POINTER_MOTION_HINT_MASK);
636 attributes_mask = GDK_WA_X | GDK_WA_Y;
638 priv->input_window = gdk_window_new (gtk_widget_get_window (widget),
639 &attributes, attributes_mask);
640 gdk_window_set_user_data (priv->input_window, ruler);
642 gtk_shruler_make_pixmap (ruler);
646 gtk_shruler_unrealize (GtkWidget *widget)
648 GtkSHRuler *ruler = GTK_SHRULER (widget);
649 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (ruler);
651 if (priv->backing_store)
653 cairo_surface_destroy (priv->backing_store);
654 priv->backing_store = NULL;
659 g_object_unref (priv->layout);
663 if (priv->input_window)
665 gdk_window_destroy (priv->input_window);
666 priv->input_window = NULL;
669 GTK_WIDGET_CLASS (gtk_shruler_parent_class)->unrealize (widget);
673 gtk_shruler_map (GtkWidget *widget)
675 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (widget);
677 GTK_WIDGET_CLASS (parent_class)->map (widget);
679 if (priv->input_window)
680 gdk_window_show (priv->input_window);
684 gtk_shruler_unmap (GtkWidget *widget)
686 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (widget);
688 if (priv->input_window)
689 gdk_window_hide (priv->input_window);
691 GTK_WIDGET_CLASS (parent_class)->unmap (widget);
695 gtk_shruler_size_allocate (GtkWidget *widget,
696 GtkAllocation *allocation)
698 GtkSHRuler *ruler = GTK_SHRULER (widget);
699 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (ruler);
701 gtk_widget_set_allocation (widget, allocation);
703 if (gtk_widget_get_realized (widget))
705 gdk_window_move_resize (priv->input_window,
706 allocation->x, allocation->y,
707 allocation->width, allocation->height);
709 gtk_shruler_make_pixmap (ruler);
713 #if GTK_CHECK_VERSION(3, 0, 0)
715 gtk_shruler_get_preferred_width (GtkWidget *widget,
719 GtkRequisition requisition;
721 gtk_shruler_size_request (widget, &requisition);
723 *minimal_width = *natural_width = requisition.width;
727 gtk_shruler_get_preferred_height (GtkWidget *widget,
728 gint *minimal_height,
729 gint *natural_height)
731 GtkRequisition requisition;
733 gtk_shruler_size_request (widget, &requisition);
735 *minimal_height = *natural_height = requisition.height;
740 gtk_shruler_size_request (GtkWidget *widget,
741 GtkRequisition *requisition)
743 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (widget);
744 GtkStyle *style = gtk_widget_get_style (widget);
746 PangoRectangle ink_rect;
749 layout = gtk_shruler_get_layout (widget, "0123456789");
750 pango_layout_get_pixel_extents (layout, &ink_rect, NULL);
752 size = 2 + ink_rect.height * 1.7;
754 if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
756 requisition->width = style->xthickness * 2 + 1;
757 requisition->height = style->ythickness * 2 + size;
761 requisition->width = style->xthickness * 2 + size;
762 requisition->height = style->ythickness * 2 + 1;
767 gtk_shruler_style_set (GtkWidget *widget,
768 GtkStyle *prev_style)
770 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (widget);
772 GTK_WIDGET_CLASS (gtk_shruler_parent_class)->style_set (widget, prev_style);
774 gtk_widget_style_get (widget,
775 "font-scale", &priv->font_scale,
780 g_object_unref (priv->layout);
786 gtk_shruler_motion_notify (GtkWidget *widget,
787 GdkEventMotion *event)
789 GtkSHRuler *ruler = GTK_SHRULER (widget);
791 gdk_event_request_motions (event);
793 gtk_shruler_update_position (ruler, event->x, event->y);
798 #if !GTK_CHECK_VERSION(3, 0, 0)
800 gtk_shruler_expose (GtkWidget *widget,
801 GdkEventExpose *event)
804 gtk_shruler_expose (GtkWidget *widget,
808 if (gtk_widget_is_drawable (widget))
810 GtkSHRuler *ruler = GTK_SHRULER (widget);
811 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (ruler);
812 GtkAllocation allocation;
813 #if !GTK_CHECK_VERSION(3, 0, 0)
817 gtk_shruler_draw_ticks (ruler);
819 #if !GTK_CHECK_VERSION(3, 0, 0)
820 cr = gdk_cairo_create (gtk_widget_get_window (widget));
821 gdk_cairo_region (cr, event->region);
825 gtk_widget_get_allocation (widget, &allocation);
826 #if !GTK_CHECK_VERSION(3, 0, 0)
827 cairo_translate (cr, allocation.x, allocation.y);
830 cairo_set_source_surface (cr, priv->backing_store, 0, 0);
833 #if !GTK_CHECK_VERSION(3, 0, 0)
842 gtk_shruler_draw_ticks (GtkSHRuler *ruler)
844 GtkWidget *widget = GTK_WIDGET (ruler);
845 GtkStyle *style = gtk_widget_get_style (widget);
846 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (ruler);
847 GtkStateType state = gtk_widget_get_state (widget);
848 GtkAllocation allocation;
855 gdouble lower, upper; /* Upper and lower limits, in ruler units */
856 gdouble increment; /* Number of pixels per unit */
857 gint scale; /* Number of units per major unit */
858 gdouble start, end, cur;
867 PangoRectangle logical_rect, ink_rect;
869 if (! gtk_widget_is_drawable (widget))
872 gtk_widget_get_allocation (widget, &allocation);
874 xthickness = style->xthickness;
875 ythickness = style->ythickness;
877 layout = gtk_shruler_get_layout (widget, "0123456789");
878 pango_layout_get_extents (layout, &ink_rect, &logical_rect);
880 digit_height = PANGO_PIXELS (ink_rect.height) + 2;
881 digit_offset = ink_rect.y;
883 if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
885 width = allocation.width;
886 height = allocation.height - ythickness * 2;
890 width = allocation.height;
891 height = allocation.width - ythickness * 2;
894 cr = cairo_create (priv->backing_store);
895 gdk_cairo_set_source_color (cr, &style->bg[state]);
899 gdk_cairo_set_source_color (cr, &style->fg[state]);
901 gtk_shruler_get_range (ruler, &lower, &upper, &max_size);
903 if ((upper - lower) == 0)
906 increment = (gdouble) width / (upper - lower);
908 /* determine the scale
909 * use the maximum extents of the ruler to determine the largest
910 * possible number to be displayed. Calculate the height in pixels
911 * of this displayed text. Use this height to find a scale which
912 * leaves sufficient room for drawing the ruler.
914 * We calculate the text size as for the vruler instead of
915 * actually measuring the text width, so that the result for the
916 * scale looks consistent with an accompanying vruler.
918 scale = ceil (max_size);
919 g_snprintf (unit_str, sizeof (unit_str), "%d", scale);
920 text_size = strlen (unit_str) * digit_height + 1;
922 for (scale = 0; scale < G_N_ELEMENTS (ruler_metric.ruler_scale); scale++)
923 if (ruler_metric.ruler_scale[scale] * fabs (increment) > 2 * text_size)
926 if (scale == G_N_ELEMENTS (ruler_metric.ruler_scale))
927 scale = G_N_ELEMENTS (ruler_metric.ruler_scale) - 1;
929 unit = gtk_shruler_get_unit (ruler);
931 /* drawing starts here */
933 for (i = G_N_ELEMENTS (ruler_metric.subdivide) - 1; i >= 0; i--)
937 /* hack to get proper subdivisions at full pixels */
938 if (unit == CM_UNIT_PIXEL && scale == 1 && i == 1)
941 subd_incr = ((gdouble) ruler_metric.ruler_scale[scale] /
942 (gdouble) ruler_metric.subdivide[i]);
944 if (subd_incr * fabs (increment) <= MINIMUM_INCR)
947 /* don't subdivide pixels */
948 if (unit == CM_UNIT_PIXEL && subd_incr < 1.0)
953 start = floor (lower / subd_incr) * subd_incr;
954 end = ceil (upper / subd_incr) * subd_incr;
958 start = floor (upper / subd_incr) * subd_incr;
959 end = ceil (lower / subd_incr) * subd_incr;
962 for (cur = start; cur <= end; cur += subd_incr)
964 if (((int)cur) % 10 == 0)
965 length = height * 2 / 3;
966 else if (((int)cur) % 5 == 0)
971 pos = ROUND ((cur - lower) * increment);
973 if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
976 pos, height + ythickness - length,
982 height + xthickness - length, pos,
987 if (i == 0 && ((int)cur) % 10 == 0)
989 g_snprintf (unit_str, sizeof (unit_str), "%d", (int) cur);
991 if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
993 pango_layout_set_text (layout, unit_str, -1);
994 pango_layout_get_extents (layout, &logical_rect, NULL);
998 ythickness + PANGO_PIXELS (logical_rect.y - digit_offset));
999 pango_cairo_show_layout (cr, layout);
1005 for (j = 0; j < (int) strlen (unit_str); j++)
1007 pango_layout_set_text (layout, unit_str + j, 1);
1008 pango_layout_get_extents (layout, NULL, &logical_rect);
1012 pos + digit_height * j + 2 + PANGO_PIXELS (logical_rect.y - digit_offset));
1013 pango_cairo_show_layout (cr, layout);
1025 static cairo_surface_t *
1026 cm_gdk_window_create_similar_surface (GdkWindow * window,
1027 cairo_content_t content,
1031 #if !GTK_CHECK_VERSION(2, 22, 0)
1032 cairo_surface_t *window_surface, *surface;
1034 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
1036 window_surface = GDK_DRAWABLE_GET_CLASS(window)->ref_cairo_surface(window);
1038 surface = cairo_surface_create_similar (window_surface,
1042 cairo_surface_destroy (window_surface);
1046 return gdk_window_create_similar_surface(window, content, width, height);
1051 gtk_shruler_make_pixmap (GtkSHRuler *ruler)
1053 GtkWidget *widget = GTK_WIDGET (ruler);
1054 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (ruler);
1055 GtkAllocation allocation;
1057 gtk_widget_get_allocation (widget, &allocation);
1059 if (priv->backing_store)
1060 cairo_surface_destroy (priv->backing_store);
1062 priv->backing_store =
1063 cm_gdk_window_create_similar_surface (gtk_widget_get_window (widget),
1064 CAIRO_CONTENT_COLOR,
1070 static PangoLayout *
1071 gtk_shruler_create_layout (GtkWidget *widget,
1074 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (widget);
1075 PangoLayout *layout;
1076 PangoAttrList *attrs;
1077 PangoAttribute *attr;
1079 layout = gtk_widget_create_pango_layout (widget, text);
1081 attrs = pango_attr_list_new ();
1083 attr = pango_attr_scale_new (priv->font_scale);
1084 attr->start_index = 0;
1085 attr->end_index = -1;
1086 pango_attr_list_insert (attrs, attr);
1088 pango_layout_set_attributes (layout, attrs);
1089 pango_attr_list_unref (attrs);
1094 static PangoLayout *
1095 gtk_shruler_get_layout (GtkWidget *widget,
1098 GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (widget);
1102 pango_layout_set_text (priv->layout, text, -1);
1103 return priv->layout;
1106 priv->layout = gtk_shruler_create_layout (widget, text);
1108 return priv->layout;