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 static void gtk_shruler_get_preferred_height (GtkWidget
*widget
,
154 gint
*minimal_height
,
155 gint
*natural_height
);
156 static void gtk_shruler_get_preferred_width (GtkWidget
*widget
,
158 gint
*natural_width
);
159 static void gtk_shruler_size_request (GtkWidget
*widget
,
160 GtkRequisition
*requisition
);
161 static void gtk_shruler_style_set (GtkWidget
*widget
,
162 GtkStyle
*prev_style
);
163 static gboolean
gtk_shruler_motion_notify (GtkWidget
*widget
,
164 GdkEventMotion
*event
);
165 static gboolean
gtk_shruler_expose (GtkWidget
*widget
,
168 static void gtk_shruler_draw_ticks (GtkSHRuler
*ruler
);
169 static void gtk_shruler_make_pixmap (GtkSHRuler
*ruler
);
171 static PangoLayout
* gtk_shruler_get_layout (GtkWidget
*widget
,
174 G_DEFINE_TYPE_WITH_CODE (GtkSHRuler
, gtk_shruler
, GTK_TYPE_WIDGET
,
175 G_ADD_PRIVATE(GtkSHRuler
))
177 #define parent_class gtk_shruler_parent_class
181 gtk_shruler_class_init (GtkSHRulerClass
*klass
)
183 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
184 GtkWidgetClass
*widget_class
= GTK_WIDGET_CLASS (klass
);
186 object_class
->dispose
= gtk_shruler_dispose
;
187 object_class
->set_property
= gtk_shruler_set_property
;
188 object_class
->get_property
= gtk_shruler_get_property
;
190 widget_class
->realize
= gtk_shruler_realize
;
191 widget_class
->unrealize
= gtk_shruler_unrealize
;
192 widget_class
->map
= gtk_shruler_map
;
193 widget_class
->unmap
= gtk_shruler_unmap
;
194 widget_class
->size_allocate
= gtk_shruler_size_allocate
;
195 widget_class
->get_preferred_width
= gtk_shruler_get_preferred_width
;
196 widget_class
->get_preferred_height
= gtk_shruler_get_preferred_height
;
197 widget_class
->style_set
= gtk_shruler_style_set
;
198 widget_class
->motion_notify_event
= gtk_shruler_motion_notify
;
199 widget_class
->draw
= gtk_shruler_expose
;
201 g_object_class_install_property (object_class
,
203 g_param_spec_enum ("orientation",
205 "The orientation of the ruler",
206 GTK_TYPE_ORIENTATION
,
207 GTK_ORIENTATION_HORIZONTAL
,
208 GTK_PARAM_READWRITE
));
210 g_object_class_install_property (object_class
,
212 gtk_param_spec_unit ("unit",
217 GTK_PARAM_READWRITE
));
219 g_object_class_install_property (object_class
,
221 g_param_spec_double ("lower",
223 "Lower limit of ruler",
227 GTK_PARAM_READWRITE
));
229 g_object_class_install_property (object_class
,
231 g_param_spec_double ("upper",
233 "Upper limit of ruler",
237 GTK_PARAM_READWRITE
));
239 g_object_class_install_property (object_class
,
241 g_param_spec_double ("position",
243 "Position of mark on the ruler",
247 GTK_PARAM_READWRITE
));
249 g_object_class_install_property (object_class
,
251 g_param_spec_double ("max-size",
253 "Maximum size of the ruler",
257 GTK_PARAM_READWRITE
));
259 gtk_widget_class_install_style_property (widget_class
,
260 g_param_spec_double ("font-scale",
264 DEFAULT_RULER_FONT_SCALE
,
265 GTK_PARAM_READABLE
));
269 gtk_shruler_init (GtkSHRuler
*ruler
)
271 GtkSHRulerPrivate
*priv
= GTK_SHRULER_GET_PRIVATE (ruler
);
273 gtk_widget_set_has_window (GTK_WIDGET (ruler
), FALSE
);
275 priv
->orientation
= GTK_ORIENTATION_HORIZONTAL
;
281 priv
->backing_store
= NULL
;
282 priv
->font_scale
= DEFAULT_RULER_FONT_SCALE
;
286 gtk_shruler_dispose (GObject
*object
)
288 G_OBJECT_CLASS (parent_class
)->dispose (object
);
292 gtk_shruler_set_property (GObject
*object
,
297 GtkSHRuler
*ruler
= GTK_SHRULER (object
);
298 GtkSHRulerPrivate
*priv
= GTK_SHRULER_GET_PRIVATE (ruler
);
302 case PROP_ORIENTATION
:
303 priv
->orientation
= g_value_get_enum (value
);
304 gtk_widget_queue_resize (GTK_WIDGET (ruler
));
308 gtk_shruler_set_unit (ruler
, g_value_get_int (value
));
312 gtk_shruler_set_range (ruler
,
313 g_value_get_double (value
),
318 gtk_shruler_set_range (ruler
,
320 g_value_get_double (value
),
325 gtk_shruler_set_position (ruler
, g_value_get_double (value
));
329 gtk_shruler_set_range (ruler
,
332 g_value_get_double (value
));
336 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
342 gtk_shruler_get_property (GObject
*object
,
347 GtkSHRuler
*ruler
= GTK_SHRULER (object
);
348 GtkSHRulerPrivate
*priv
= GTK_SHRULER_GET_PRIVATE (ruler
);
352 case PROP_ORIENTATION
:
353 g_value_set_enum (value
, priv
->orientation
);
357 g_value_set_int (value
, priv
->unit
);
361 g_value_set_double (value
, priv
->lower
);
365 g_value_set_double (value
, priv
->upper
);
369 g_value_set_double (value
, priv
->position
);
373 g_value_set_double (value
, priv
->max_size
);
377 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
384 * @orientation: the ruler's orientation.
386 * Creates a new ruler.
388 * Return value: a new #GtkSHRuler widget.
393 gtk_shruler_new (GtkOrientation orientation
)
395 return g_object_new (GTK_TYPE_SHRULER
,
396 "orientation", orientation
,
401 gtk_shruler_update_position (GtkSHRuler
*ruler
,
405 GtkSHRulerPrivate
*priv
= GTK_SHRULER_GET_PRIVATE (ruler
);
406 GtkAllocation allocation
;
410 gtk_widget_get_allocation (GTK_WIDGET (ruler
), &allocation
);
411 gtk_shruler_get_range (ruler
, &lower
, &upper
, NULL
);
413 if (priv
->orientation
== GTK_ORIENTATION_HORIZONTAL
)
415 gtk_shruler_set_position (ruler
,
417 (upper
- lower
) * x
/ allocation
.width
);
421 gtk_shruler_set_position (ruler
,
423 (upper
- lower
) * y
/ allocation
.height
);
428 * gtk_shruler_set_unit:
429 * @ruler: a #GtkSHRuler
430 * @unit: the #GtkCMUnit to set the ruler to
432 * This sets the unit of the ruler.
437 gtk_shruler_set_unit (GtkSHRuler
*ruler
,
440 GtkSHRulerPrivate
*priv
;
442 g_return_if_fail (GTK_IS_SHRULER (ruler
));
444 priv
= GTK_SHRULER_GET_PRIVATE (ruler
);
446 if (priv
->unit
!= unit
)
449 g_object_notify (G_OBJECT (ruler
), "unit");
451 gtk_widget_queue_draw (GTK_WIDGET (ruler
));
456 * gtk_shruler_get_unit:
457 * @ruler: a #GtkSHRuler
459 * Return value: the unit currently used in the @ruler widget.
464 gtk_shruler_get_unit (GtkSHRuler
*ruler
)
466 g_return_val_if_fail (GTK_IS_SHRULER (ruler
), 0);
468 return GTK_SHRULER_GET_PRIVATE (ruler
)->unit
;
472 * gtk_shruler_set_position:
473 * @ruler: a #GtkSHRuler
474 * @position: the position to set the ruler to
476 * This sets the position of the ruler.
481 gtk_shruler_set_position (GtkSHRuler
*ruler
,
484 GtkSHRulerPrivate
*priv
;
486 g_return_if_fail (GTK_IS_SHRULER (ruler
));
488 priv
= GTK_SHRULER_GET_PRIVATE (ruler
);
490 if (priv
->position
!= position
)
492 priv
->position
= position
;
493 g_object_notify (G_OBJECT (ruler
), "position");
498 * gtk_shruler_get_position:
499 * @ruler: a #GtkSHRuler
501 * Return value: the current position of the @ruler widget.
506 gtk_shruler_get_position (GtkSHRuler
*ruler
)
508 g_return_val_if_fail (GTK_IS_SHRULER (ruler
), 0.0);
510 return GTK_SHRULER_GET_PRIVATE (ruler
)->position
;
514 * gtk_shruler_set_range:
515 * @ruler: a #GtkSHRuler
516 * @lower: the lower limit of the ruler
517 * @upper: the upper limit of the ruler
518 * @max_size: the maximum size of the ruler used when calculating the space to
521 * This sets the range of the ruler.
526 gtk_shruler_set_range (GtkSHRuler
*ruler
,
531 GtkSHRulerPrivate
*priv
;
533 g_return_if_fail (GTK_IS_SHRULER (ruler
));
535 priv
= GTK_SHRULER_GET_PRIVATE (ruler
);
537 g_object_freeze_notify (G_OBJECT (ruler
));
538 if (priv
->lower
!= lower
)
541 g_object_notify (G_OBJECT (ruler
), "lower");
543 if (priv
->upper
!= upper
)
546 g_object_notify (G_OBJECT (ruler
), "upper");
548 if (priv
->max_size
!= max_size
)
550 priv
->max_size
= max_size
;
551 g_object_notify (G_OBJECT (ruler
), "max-size");
553 g_object_thaw_notify (G_OBJECT (ruler
));
555 gtk_widget_queue_draw (GTK_WIDGET (ruler
));
559 * gtk_shruler_get_range:
560 * @ruler: a #GtkSHRuler
561 * @lower: location to store lower limit of the ruler, or %NULL
562 * @upper: location to store upper limit of the ruler, or %NULL
563 * @max_size: location to store the maximum size of the ruler used when
564 * calculating the space to leave for the text, or %NULL.
566 * Retrieves values indicating the range and current position of a #GtkSHRuler.
567 * See gtk_shruler_set_range().
572 gtk_shruler_get_range (GtkSHRuler
*ruler
,
577 GtkSHRulerPrivate
*priv
;
579 g_return_if_fail (GTK_IS_SHRULER (ruler
));
581 priv
= GTK_SHRULER_GET_PRIVATE (ruler
);
584 *lower
= priv
->lower
;
586 *upper
= priv
->upper
;
588 *max_size
= priv
->max_size
;
592 gtk_shruler_realize (GtkWidget
*widget
)
594 GtkSHRuler
*ruler
= GTK_SHRULER (widget
);
595 GtkSHRulerPrivate
*priv
= GTK_SHRULER_GET_PRIVATE (ruler
);
596 GtkAllocation allocation
;
597 GdkWindowAttr attributes
;
598 gint attributes_mask
;
600 GTK_WIDGET_CLASS (gtk_shruler_parent_class
)->realize (widget
);
602 gtk_widget_get_allocation (widget
, &allocation
);
604 attributes
.window_type
= GDK_WINDOW_CHILD
;
605 attributes
.x
= allocation
.x
;
606 attributes
.y
= allocation
.y
;
607 attributes
.width
= allocation
.width
;
608 attributes
.height
= allocation
.height
;
609 attributes
.wclass
= GDK_INPUT_ONLY
;
610 attributes
.event_mask
= (gtk_widget_get_events (widget
) |
612 GDK_POINTER_MOTION_MASK
|
613 GDK_POINTER_MOTION_HINT_MASK
);
615 attributes_mask
= GDK_WA_X
| GDK_WA_Y
;
617 priv
->input_window
= gdk_window_new (gtk_widget_get_window (widget
),
618 &attributes
, attributes_mask
);
619 gtk_widget_register_window (widget
, priv
->input_window
);
621 gtk_shruler_make_pixmap (ruler
);
625 gtk_shruler_unrealize (GtkWidget
*widget
)
627 GtkSHRuler
*ruler
= GTK_SHRULER (widget
);
628 GtkSHRulerPrivate
*priv
= GTK_SHRULER_GET_PRIVATE (ruler
);
630 if (priv
->backing_store
)
632 cairo_surface_destroy (priv
->backing_store
);
633 priv
->backing_store
= NULL
;
638 g_object_unref (priv
->layout
);
642 if (priv
->input_window
)
644 gtk_widget_unregister_window (widget
, priv
->input_window
);
645 gdk_window_destroy (priv
->input_window
);
646 priv
->input_window
= NULL
;
649 GTK_WIDGET_CLASS (gtk_shruler_parent_class
)->unrealize (widget
);
653 gtk_shruler_map (GtkWidget
*widget
)
655 GtkSHRulerPrivate
*priv
= GTK_SHRULER_GET_PRIVATE (widget
);
657 GTK_WIDGET_CLASS (parent_class
)->map (widget
);
659 if (priv
->input_window
)
660 gdk_window_show (priv
->input_window
);
664 gtk_shruler_unmap (GtkWidget
*widget
)
666 GtkSHRulerPrivate
*priv
= GTK_SHRULER_GET_PRIVATE (widget
);
668 if (priv
->input_window
)
669 gdk_window_hide (priv
->input_window
);
671 GTK_WIDGET_CLASS (parent_class
)->unmap (widget
);
675 gtk_shruler_size_allocate (GtkWidget
*widget
,
676 GtkAllocation
*allocation
)
678 GtkSHRuler
*ruler
= GTK_SHRULER (widget
);
679 GtkSHRulerPrivate
*priv
= GTK_SHRULER_GET_PRIVATE (ruler
);
681 gtk_widget_set_allocation (widget
, allocation
);
683 if (gtk_widget_get_realized (widget
))
685 gdk_window_move_resize (priv
->input_window
,
686 allocation
->x
, allocation
->y
,
687 allocation
->width
, allocation
->height
);
689 gtk_shruler_make_pixmap (ruler
);
694 gtk_shruler_get_preferred_width (GtkWidget
*widget
,
698 GtkRequisition requisition
;
700 gtk_shruler_size_request (widget
, &requisition
);
702 *minimal_width
= *natural_width
= requisition
.width
;
706 gtk_shruler_get_preferred_height (GtkWidget
*widget
,
707 gint
*minimal_height
,
708 gint
*natural_height
)
710 GtkRequisition requisition
;
712 gtk_shruler_size_request (widget
, &requisition
);
714 *minimal_height
= *natural_height
= requisition
.height
;
718 gtk_shruler_size_request (GtkWidget
*widget
,
719 GtkRequisition
*requisition
)
721 GtkSHRulerPrivate
*priv
= GTK_SHRULER_GET_PRIVATE (widget
);
722 GtkStyle
*style
= gtk_widget_get_style (widget
);
724 PangoRectangle ink_rect
;
727 layout
= gtk_shruler_get_layout (widget
, "0123456789");
728 pango_layout_get_pixel_extents (layout
, &ink_rect
, NULL
);
730 size
= 2 + ink_rect
.height
* 1.7;
732 if (priv
->orientation
== GTK_ORIENTATION_HORIZONTAL
)
734 requisition
->width
= style
->xthickness
* 2 + 1;
735 requisition
->height
= style
->ythickness
* 2 + size
;
739 requisition
->width
= style
->xthickness
* 2 + size
;
740 requisition
->height
= style
->ythickness
* 2 + 1;
745 gtk_shruler_style_set (GtkWidget
*widget
,
746 GtkStyle
*prev_style
)
748 GtkSHRulerPrivate
*priv
= GTK_SHRULER_GET_PRIVATE (widget
);
750 GTK_WIDGET_CLASS (gtk_shruler_parent_class
)->style_set (widget
, prev_style
);
752 gtk_widget_style_get (widget
,
753 "font-scale", &priv
->font_scale
,
758 g_object_unref (priv
->layout
);
764 gtk_shruler_motion_notify (GtkWidget
*widget
,
765 GdkEventMotion
*event
)
767 GtkSHRuler
*ruler
= GTK_SHRULER (widget
);
769 gdk_event_request_motions (event
);
771 gtk_shruler_update_position (ruler
, event
->x
, event
->y
);
777 gtk_shruler_expose (GtkWidget
*widget
,
780 if (gtk_widget_is_drawable (widget
))
782 GtkSHRuler
*ruler
= GTK_SHRULER (widget
);
783 GtkSHRulerPrivate
*priv
= GTK_SHRULER_GET_PRIVATE (ruler
);
784 GtkAllocation allocation
;
786 gtk_shruler_draw_ticks (ruler
);
788 gtk_widget_get_allocation (widget
, &allocation
);
790 cairo_set_source_surface (cr
, priv
->backing_store
, 0, 0);
798 gtk_shruler_draw_ticks (GtkSHRuler
*ruler
)
800 GtkWidget
*widget
= GTK_WIDGET (ruler
);
801 GtkStyle
*style
= gtk_widget_get_style (widget
);
802 GtkSHRulerPrivate
*priv
= GTK_SHRULER_GET_PRIVATE (ruler
);
803 GtkStateType state
= gtk_widget_get_state (widget
);
804 GtkAllocation allocation
;
811 gdouble lower
, upper
; /* Upper and lower limits, in ruler units */
812 gdouble increment
; /* Number of pixels per unit */
813 gint scale
; /* Number of units per major unit */
814 gdouble start
, end
, cur
;
823 PangoRectangle logical_rect
, ink_rect
;
825 if (! gtk_widget_is_drawable (widget
))
828 gtk_widget_get_allocation (widget
, &allocation
);
830 xthickness
= style
->xthickness
;
831 ythickness
= style
->ythickness
;
833 layout
= gtk_shruler_get_layout (widget
, "0123456789");
834 pango_layout_get_extents (layout
, &ink_rect
, &logical_rect
);
836 digit_height
= PANGO_PIXELS (ink_rect
.height
) + 2;
837 digit_offset
= ink_rect
.y
;
839 if (priv
->orientation
== GTK_ORIENTATION_HORIZONTAL
)
841 width
= allocation
.width
;
842 height
= allocation
.height
- ythickness
* 2;
846 width
= allocation
.height
;
847 height
= allocation
.width
- ythickness
* 2;
850 cr
= cairo_create (priv
->backing_store
);
851 gdk_cairo_set_source_color (cr
, &style
->bg
[state
]);
855 gdk_cairo_set_source_color (cr
, &style
->fg
[state
]);
857 gtk_shruler_get_range (ruler
, &lower
, &upper
, &max_size
);
859 if ((upper
- lower
) == 0)
862 increment
= (gdouble
) width
/ (upper
- lower
);
864 /* determine the scale
865 * use the maximum extents of the ruler to determine the largest
866 * possible number to be displayed. Calculate the height in pixels
867 * of this displayed text. Use this height to find a scale which
868 * leaves sufficient room for drawing the ruler.
870 * We calculate the text size as for the vruler instead of
871 * actually measuring the text width, so that the result for the
872 * scale looks consistent with an accompanying vruler.
874 scale
= ceil (max_size
);
875 g_snprintf (unit_str
, sizeof (unit_str
), "%d", scale
);
876 text_size
= strlen (unit_str
) * digit_height
+ 1;
878 for (scale
= 0; scale
< G_N_ELEMENTS (ruler_metric
.ruler_scale
); scale
++)
879 if (ruler_metric
.ruler_scale
[scale
] * fabs (increment
) > 2 * text_size
)
882 if (scale
== G_N_ELEMENTS (ruler_metric
.ruler_scale
))
883 scale
= G_N_ELEMENTS (ruler_metric
.ruler_scale
) - 1;
885 unit
= gtk_shruler_get_unit (ruler
);
887 /* drawing starts here */
889 for (i
= G_N_ELEMENTS (ruler_metric
.subdivide
) - 1; i
>= 0; i
--)
893 /* hack to get proper subdivisions at full pixels */
894 if (unit
== CM_UNIT_PIXEL
&& scale
== 1 && i
== 1)
897 subd_incr
= ((gdouble
) ruler_metric
.ruler_scale
[scale
] /
898 (gdouble
) ruler_metric
.subdivide
[i
]);
900 if (subd_incr
* fabs (increment
) <= MINIMUM_INCR
)
903 /* don't subdivide pixels */
904 if (unit
== CM_UNIT_PIXEL
&& subd_incr
< 1.0)
909 start
= floor (lower
/ subd_incr
) * subd_incr
;
910 end
= ceil (upper
/ subd_incr
) * subd_incr
;
914 start
= floor (upper
/ subd_incr
) * subd_incr
;
915 end
= ceil (lower
/ subd_incr
) * subd_incr
;
918 for (cur
= start
; cur
<= end
; cur
+= subd_incr
)
920 if (((int)cur
) % 10 == 0)
921 length
= height
* 2 / 3;
922 else if (((int)cur
) % 5 == 0)
927 pos
= ROUND ((cur
- lower
) * increment
);
929 if (priv
->orientation
== GTK_ORIENTATION_HORIZONTAL
)
932 pos
, height
+ ythickness
- length
,
938 height
+ xthickness
- length
, pos
,
943 if (i
== 0 && ((int)cur
) % 10 == 0)
945 g_snprintf (unit_str
, sizeof (unit_str
), "%d", (int) cur
);
947 if (priv
->orientation
== GTK_ORIENTATION_HORIZONTAL
)
949 pango_layout_set_text (layout
, unit_str
, -1);
950 pango_layout_get_extents (layout
, &logical_rect
, NULL
);
954 ythickness
+ PANGO_PIXELS (logical_rect
.y
- digit_offset
));
955 pango_cairo_show_layout (cr
, layout
);
961 for (j
= 0; j
< (int) strlen (unit_str
); j
++)
963 pango_layout_set_text (layout
, unit_str
+ j
, 1);
964 pango_layout_get_extents (layout
, NULL
, &logical_rect
);
968 pos
+ digit_height
* j
+ 2 + PANGO_PIXELS (logical_rect
.y
- digit_offset
));
969 pango_cairo_show_layout (cr
, layout
);
982 gtk_shruler_make_pixmap (GtkSHRuler
*ruler
)
984 GtkWidget
*widget
= GTK_WIDGET (ruler
);
985 GtkSHRulerPrivate
*priv
= GTK_SHRULER_GET_PRIVATE (ruler
);
986 GtkAllocation allocation
;
988 gtk_widget_get_allocation (widget
, &allocation
);
990 if (priv
->backing_store
)
991 cairo_surface_destroy (priv
->backing_store
);
993 priv
->backing_store
=
994 gdk_window_create_similar_surface (gtk_widget_get_window (widget
),
1001 static PangoLayout
*
1002 gtk_shruler_create_layout (GtkWidget
*widget
,
1005 GtkSHRulerPrivate
*priv
= GTK_SHRULER_GET_PRIVATE (widget
);
1006 PangoLayout
*layout
;
1007 PangoAttrList
*attrs
;
1008 PangoAttribute
*attr
;
1010 layout
= gtk_widget_create_pango_layout (widget
, text
);
1012 attrs
= pango_attr_list_new ();
1014 attr
= pango_attr_scale_new (priv
->font_scale
);
1015 attr
->start_index
= 0;
1016 attr
->end_index
= -1;
1017 pango_attr_list_insert (attrs
, attr
);
1019 pango_layout_set_attributes (layout
, attrs
);
1020 pango_attr_list_unref (attrs
);
1025 static PangoLayout
*
1026 gtk_shruler_get_layout (GtkWidget
*widget
,
1029 GtkSHRulerPrivate
*priv
= GTK_SHRULER_GET_PRIVATE (widget
);
1033 pango_layout_set_text (priv
->layout
, text
, -1);
1034 return priv
->layout
;
1037 priv
->layout
= gtk_shruler_create_layout (widget
, text
);
1039 return priv
->layout
;