Compare commits
15 Commits
class-shor
...
css-line-h
Author | SHA1 | Date | |
---|---|---|---|
|
d47392487f | ||
|
1394f73ce2 | ||
|
4a5025eca1 | ||
|
be8cbb2adb | ||
|
3c9edc1afa | ||
|
630bbf8d9b | ||
|
8eb82da896 | ||
|
a457a81fd9 | ||
|
e5e7f5dd88 | ||
|
916886312a | ||
|
8ff94ea1f2 | ||
|
053bd0cd31 | ||
|
a3ce574193 | ||
|
ef92adc87d | ||
|
46a9538b6a |
@@ -2146,7 +2146,7 @@ gsk_outset_shadow_get_extents (GskOutsetShadowNode *self,
|
||||
{
|
||||
float clip_radius;
|
||||
|
||||
clip_radius = gsk_cairo_blur_compute_pixels (self->blur_radius);
|
||||
clip_radius = gsk_cairo_blur_compute_pixels (self->blur_radius / 2.0);
|
||||
*top = MAX (0, clip_radius + self->spread - self->dy);
|
||||
*right = MAX (0, ceil (clip_radius + self->spread + self->dx));
|
||||
*bottom = MAX (0, ceil (clip_radius + self->spread + self->dy));
|
||||
@@ -3852,7 +3852,7 @@ gsk_shadow_node_diff (GskRenderNode *node1,
|
||||
return;
|
||||
}
|
||||
|
||||
clip_radius = gsk_cairo_blur_compute_pixels (shadow1->radius);
|
||||
clip_radius = gsk_cairo_blur_compute_pixels (shadow1->radius / 2.0);
|
||||
top = MAX (top, ceil (clip_radius - shadow1->dy));
|
||||
right = MAX (right, ceil (clip_radius + shadow1->dx));
|
||||
bottom = MAX (bottom, ceil (clip_radius + shadow1->dy));
|
||||
@@ -3886,7 +3886,7 @@ gsk_shadow_node_get_bounds (GskShadowNode *self,
|
||||
|
||||
for (i = 0; i < self->n_shadows; i++)
|
||||
{
|
||||
float clip_radius = gsk_cairo_blur_compute_pixels (self->shadows[i].radius);
|
||||
float clip_radius = gsk_cairo_blur_compute_pixels (self->shadows[i].radius / 2.0);
|
||||
top = MAX (top, clip_radius - self->shadows[i].dy);
|
||||
right = MAX (right, clip_radius + self->shadows[i].dx);
|
||||
bottom = MAX (bottom, clip_radius + self->shadows[i].dy);
|
||||
@@ -4866,7 +4866,7 @@ gsk_blur_node_diff (GskRenderNode *node1,
|
||||
cairo_region_t *sub;
|
||||
int i, n, clip_radius;
|
||||
|
||||
clip_radius = ceil (gsk_cairo_blur_compute_pixels (self1->radius));
|
||||
clip_radius = ceil (gsk_cairo_blur_compute_pixels (self1->radius / 2.0));
|
||||
sub = cairo_region_create ();
|
||||
gsk_render_node_diff (self1->child, self2->child, sub);
|
||||
|
||||
@@ -4913,7 +4913,7 @@ gsk_blur_node_new (GskRenderNode *child,
|
||||
self->child = gsk_render_node_ref (child);
|
||||
self->radius = radius;
|
||||
|
||||
clip_radius = gsk_cairo_blur_compute_pixels (radius);
|
||||
clip_radius = gsk_cairo_blur_compute_pixels (radius / 2.0);
|
||||
|
||||
graphene_rect_init_from_rect (&node->bounds, &child->bounds);
|
||||
graphene_rect_inset (&self->render_node.bounds,
|
||||
|
@@ -204,6 +204,10 @@ gtk_css_animated_style_set_animated_value (GtkCssAnimatedStyle *animated,
|
||||
unshare_font (animated);
|
||||
gtk_css_take_value (&style->font->letter_spacing, value);
|
||||
break;
|
||||
case GTK_CSS_PROPERTY_LINE_HEIGHT:
|
||||
unshare_font (animated);
|
||||
gtk_css_take_value (&style->font->line_height, value);
|
||||
break;
|
||||
case GTK_CSS_PROPERTY_TEXT_DECORATION_LINE:
|
||||
unshare_font_variant (animated);
|
||||
gtk_css_take_value (&style->font_variant->text_decoration_line, value);
|
||||
|
@@ -542,8 +542,8 @@ gtk_css_shadow_value_get_extents (const GtkCssValue *value,
|
||||
|
||||
spread = _gtk_css_number_value_get (shadow->spread, 0);
|
||||
radius = _gtk_css_number_value_get (shadow->radius, 0);
|
||||
if (value->is_filter)
|
||||
radius = radius * 2;
|
||||
if (!value->is_filter)
|
||||
radius = radius / 2.0;
|
||||
clip_radius = gsk_cairo_blur_compute_pixels (radius);
|
||||
hoffset = _gtk_css_number_value_get (shadow->hoffset, 0);
|
||||
voffset = _gtk_css_number_value_get (shadow->voffset, 0);
|
||||
|
@@ -107,11 +107,12 @@ static const int font_props[] = {
|
||||
GTK_CSS_PROPERTY_FONT_WEIGHT,
|
||||
GTK_CSS_PROPERTY_FONT_STRETCH,
|
||||
GTK_CSS_PROPERTY_LETTER_SPACING,
|
||||
GTK_CSS_PROPERTY_TEXT_SHADOW,
|
||||
GTK_CSS_PROPERTY_TEXT_SHADOW,
|
||||
GTK_CSS_PROPERTY_CARET_COLOR,
|
||||
GTK_CSS_PROPERTY_SECONDARY_CARET_COLOR,
|
||||
GTK_CSS_PROPERTY_FONT_FEATURE_SETTINGS,
|
||||
GTK_CSS_PROPERTY_FONT_VARIATION_SETTINGS,
|
||||
GTK_CSS_PROPERTY_LINE_HEIGHT,
|
||||
};
|
||||
static const int font_variant_props[] = {
|
||||
GTK_CSS_PROPERTY_TEXT_DECORATION_LINE,
|
||||
@@ -417,6 +418,9 @@ gtk_css_static_style_set_value (GtkCssStaticStyle *sstyle,
|
||||
case GTK_CSS_PROPERTY_LETTER_SPACING:
|
||||
gtk_css_take_value (&style->font->letter_spacing, value);
|
||||
break;
|
||||
case GTK_CSS_PROPERTY_LINE_HEIGHT:
|
||||
gtk_css_take_value (&style->font->line_height, value);
|
||||
break;
|
||||
case GTK_CSS_PROPERTY_TEXT_DECORATION_LINE:
|
||||
gtk_css_take_value (&style->font_variant->text_decoration_line, value);
|
||||
break;
|
||||
|
@@ -226,3 +226,13 @@ _gtk_css_ident_value_get (const GtkCssValue *value)
|
||||
return value->string;
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
gtk_css_line_height_value_get_default (void)
|
||||
{
|
||||
static GtkCssValue *normal_line_height;
|
||||
|
||||
if (normal_line_height == NULL)
|
||||
normal_line_height = _gtk_css_ident_value_new_take ("normal");
|
||||
|
||||
return normal_line_height;
|
||||
}
|
||||
|
@@ -40,6 +40,7 @@ GtkCssValue * _gtk_css_string_value_parse (GtkCssParser *par
|
||||
|
||||
const char * _gtk_css_string_value_get (const GtkCssValue *string);
|
||||
|
||||
GtkCssValue * gtk_css_line_height_value_get_default (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@@ -117,6 +117,8 @@ gtk_css_style_get_value (GtkCssStyle *style,
|
||||
return style->font->font_stretch;
|
||||
case GTK_CSS_PROPERTY_LETTER_SPACING:
|
||||
return style->font->letter_spacing;
|
||||
case GTK_CSS_PROPERTY_LINE_HEIGHT:
|
||||
return style->font->line_height;
|
||||
case GTK_CSS_PROPERTY_TEXT_DECORATION_LINE:
|
||||
return style->font_variant->text_decoration_line;
|
||||
case GTK_CSS_PROPERTY_TEXT_DECORATION_COLOR:
|
||||
|
0
gtk/gtkcssstyle.h
Normal file
0
gtk/gtkcssstyle.h
Normal file
@@ -151,6 +151,7 @@ struct _GtkCssFontValues {
|
||||
GtkCssValue *secondary_caret_color; // NULL if currentColor
|
||||
GtkCssValue *font_feature_settings;
|
||||
GtkCssValue *font_variation_settings;
|
||||
GtkCssValue *line_height;
|
||||
};
|
||||
|
||||
struct _GtkCssFontVariantValues {
|
||||
|
@@ -812,6 +812,25 @@ transform_origin_parse (GtkCssStyleProperty *property,
|
||||
return _gtk_css_position_value_parse (parser);
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
parse_line_height (GtkCssStyleProperty *property,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
GtkCssValue *value = NULL;
|
||||
|
||||
if (gtk_css_parser_try_ident (parser, "normal"))
|
||||
value = _gtk_css_ident_value_new ("normal");
|
||||
else
|
||||
value = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER |
|
||||
GTK_CSS_PARSE_PERCENT |
|
||||
GTK_CSS_POSITIVE_ONLY);
|
||||
|
||||
if (value == NULL)
|
||||
gtk_css_parser_error_syntax (parser, "Not a valid line-height value");
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/*** REGISTRATION ***/
|
||||
|
||||
G_STATIC_ASSERT (GTK_CSS_PROPERTY_COLOR == 0);
|
||||
@@ -1401,4 +1420,10 @@ _gtk_css_style_property_init_properties (void)
|
||||
GTK_CSS_AFFECTS_TEXT_ATTRS | GTK_CSS_AFFECTS_TEXT_SIZE,
|
||||
parse_font_variation_settings,
|
||||
gtk_css_font_variations_value_new_default ());
|
||||
gtk_css_style_property_register ("line-height",
|
||||
GTK_CSS_PROPERTY_LINE_HEIGHT,
|
||||
GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_ANIMATED,
|
||||
GTK_CSS_AFFECTS_TEXT_SIZE,
|
||||
parse_line_height,
|
||||
_gtk_css_value_ref (gtk_css_line_height_value_get_default ()));
|
||||
}
|
||||
|
@@ -275,6 +275,7 @@ enum { /*< skip >*/
|
||||
GTK_CSS_PROPERTY_SECONDARY_CARET_COLOR,
|
||||
GTK_CSS_PROPERTY_FONT_FEATURE_SETTINGS,
|
||||
GTK_CSS_PROPERTY_FONT_VARIATION_SETTINGS,
|
||||
GTK_CSS_PROPERTY_LINE_HEIGHT,
|
||||
/* add more */
|
||||
GTK_CSS_PROPERTY_N_PROPERTIES
|
||||
};
|
||||
|
@@ -53,6 +53,8 @@
|
||||
#include "gtkdragicon.h"
|
||||
#include "gtkcsscolorvalueprivate.h"
|
||||
#include "gtkjoinedmenuprivate.h"
|
||||
#include "gtkcssstylepropertyprivate.h"
|
||||
#include "gtkcssnumbervalueprivate.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
@@ -841,6 +843,26 @@ gtk_label_update_layout_attributes (GtkLabel *self,
|
||||
pango_attr_list_unref (attrs);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_update_layout (GtkLabel *self)
|
||||
{
|
||||
GtkCssStyle *style;
|
||||
GtkCssStyleProperty *prop;
|
||||
float line_spacing;
|
||||
|
||||
if (self->layout == NULL)
|
||||
return;
|
||||
|
||||
style = gtk_css_node_get_style (gtk_widget_get_css_node (GTK_WIDGET (self)));
|
||||
|
||||
if (_gtk_css_value_equal (style->font->line_height, gtk_css_line_height_value_get_default ()))
|
||||
line_spacing = 0.0;
|
||||
else
|
||||
line_spacing = _gtk_css_number_value_get (style->font->line_height, 1.0);
|
||||
|
||||
pango_layout_set_line_spacing (self->layout, line_spacing);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_css_changed (GtkWidget *widget,
|
||||
GtkCssStyleChange *change)
|
||||
@@ -851,6 +873,11 @@ gtk_label_css_changed (GtkWidget *widget,
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_label_parent_class)->css_changed (widget, change);
|
||||
|
||||
if (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_TEXT_SIZE))
|
||||
{
|
||||
gtk_label_update_layout (self);
|
||||
}
|
||||
|
||||
if (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_TEXT_ATTRS))
|
||||
{
|
||||
new_attrs = gtk_css_style_get_pango_attributes (gtk_css_style_change_get_new_style (change));
|
||||
@@ -860,7 +887,7 @@ gtk_label_css_changed (GtkWidget *widget,
|
||||
else
|
||||
attrs_affected = FALSE;
|
||||
|
||||
if (change == NULL || attrs_affected || (self->select_info && self->select_info->links))
|
||||
if (change == NULL || attrs_affected || (self->select_info && self->select_info->links))
|
||||
{
|
||||
gtk_label_update_layout_attributes (self, new_attrs);
|
||||
|
||||
@@ -3982,6 +4009,7 @@ gtk_label_ensure_layout (GtkLabel *self)
|
||||
self->layout = gtk_widget_create_pango_layout (GTK_WIDGET (self), self->text);
|
||||
|
||||
gtk_label_update_layout_attributes (self, NULL);
|
||||
gtk_label_update_layout (self);
|
||||
|
||||
switch (self->jtype)
|
||||
{
|
||||
|
@@ -972,6 +972,59 @@ gtk_popover_unrealize (GtkWidget *widget)
|
||||
g_clear_object (&priv->surface);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_popover_focus (GtkWidget *widget,
|
||||
GtkDirectionType direction)
|
||||
{
|
||||
if (!gtk_widget_get_visible (widget))
|
||||
return FALSE;
|
||||
|
||||
/* This code initially comes from gtkpopovermenu.c */
|
||||
if (gtk_widget_get_first_child (widget) == NULL)
|
||||
{
|
||||
/* Empty popover, so nothing to Tab through. */
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Move focus normally, but when nothing can be focused in this direction then we cycle around. */
|
||||
if (gtk_widget_focus_move (widget, direction))
|
||||
return TRUE;
|
||||
|
||||
if (gtk_popover_get_autohide (GTK_POPOVER (widget)))
|
||||
{
|
||||
GtkWidget *p = gtk_root_get_focus (gtk_widget_get_root (widget));
|
||||
|
||||
/* In the case where the popover doesn't have any focusable child (like
|
||||
* the GtkTreePopover for combo boxes) then the focus will end up out of
|
||||
* the popover, hence creating an infinite loop below. To avoid this, just
|
||||
* say we had focus and stop here.
|
||||
*/
|
||||
if (!gtk_widget_is_ancestor (p, widget) && p != widget)
|
||||
return TRUE;
|
||||
|
||||
/* Cycle around with (Shift+)Tab */
|
||||
if (direction == GTK_DIR_TAB_FORWARD || direction == GTK_DIR_TAB_BACKWARD)
|
||||
{
|
||||
for (;
|
||||
p != widget;
|
||||
p = gtk_widget_get_parent (p))
|
||||
{
|
||||
/* Unfocus everything in the popover. */
|
||||
gtk_widget_set_focus_child (p, NULL);
|
||||
}
|
||||
}
|
||||
/* Focus again from scratch */
|
||||
gtk_widget_focus_move (widget, direction);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_popover_show (GtkWidget *widget)
|
||||
{
|
||||
@@ -1734,6 +1787,7 @@ gtk_popover_class_init (GtkPopoverClass *klass)
|
||||
widget_class->unrealize = gtk_popover_unrealize;
|
||||
widget_class->map = gtk_popover_map;
|
||||
widget_class->unmap = gtk_popover_unmap;
|
||||
widget_class->focus = gtk_popover_focus;
|
||||
widget_class->show = gtk_popover_show;
|
||||
widget_class->hide = gtk_popover_hide;
|
||||
widget_class->measure = gtk_popover_measure;
|
||||
@@ -2175,8 +2229,8 @@ gtk_popover_get_position (GtkPopover *popover)
|
||||
* Sets whether @popover is modal.
|
||||
*
|
||||
* A modal popover will grab the keyboard focus on it when being
|
||||
* displayed. Clicking outside the popover area or pressing Esc
|
||||
* will dismiss the popover.
|
||||
* displayed. Focus will wrap around within the popover. Clicking
|
||||
* outside the popover area or pressing Esc will dismiss the popover.
|
||||
*
|
||||
* Called this function on an already showing popup with a new
|
||||
* autohide value different from the current one, will cause the
|
||||
|
@@ -480,12 +480,21 @@ gtk_popover_menu_focus (GtkWidget *widget,
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
else if (direction == GTK_DIR_UP || direction == GTK_DIR_DOWN)
|
||||
/* Cycle around with up/down arrows and (Shift+)Tab when modal */
|
||||
else if (gtk_popover_get_autohide (GTK_POPOVER (menu)))
|
||||
{
|
||||
GtkWidget *p;
|
||||
GtkWidget *p = gtk_root_get_focus (gtk_widget_get_root (widget));
|
||||
|
||||
/* In the case where the popover doesn't have any focusable child, if
|
||||
* the menu doesn't have any item for example, then the focus will end
|
||||
* up out of the popover, hence creating an infinite loop below. To
|
||||
* avoid this, just say we had focus and stop here.
|
||||
*/
|
||||
if (!gtk_widget_is_ancestor (p, widget) && p != widget)
|
||||
return TRUE;
|
||||
|
||||
/* cycle around */
|
||||
for (p = gtk_root_get_focus (gtk_widget_get_root (widget));
|
||||
for (;
|
||||
p != widget;
|
||||
p = gtk_widget_get_parent (p))
|
||||
{
|
||||
@@ -493,7 +502,7 @@ gtk_popover_menu_focus (GtkWidget *widget,
|
||||
}
|
||||
if (gtk_widget_focus_move (widget, direction))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
@@ -5049,39 +5049,40 @@ gtk_text_move_visually (GtkText *self,
|
||||
int index;
|
||||
PangoLayout *layout = gtk_text_ensure_layout (self, FALSE);
|
||||
const char *text;
|
||||
gboolean split_cursor;
|
||||
gboolean strong;
|
||||
|
||||
text = pango_layout_get_text (layout);
|
||||
|
||||
|
||||
index = g_utf8_offset_to_pointer (text, start) - text;
|
||||
|
||||
|
||||
g_object_get (gtk_widget_get_settings (GTK_WIDGET (self)),
|
||||
"gtk-split-cursor", &split_cursor,
|
||||
NULL);
|
||||
|
||||
if (split_cursor)
|
||||
strong = TRUE;
|
||||
else
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GdkSeat *seat;
|
||||
GdkDevice *keyboard = NULL;
|
||||
PangoDirection direction = PANGO_DIRECTION_LTR;
|
||||
|
||||
display = gtk_widget_get_display (GTK_WIDGET (self));
|
||||
seat = gdk_display_get_default_seat (display);
|
||||
if (seat)
|
||||
keyboard = gdk_seat_get_keyboard (seat);
|
||||
if (keyboard)
|
||||
direction = gdk_device_get_direction (keyboard);
|
||||
|
||||
strong = direction == priv->resolved_dir;
|
||||
}
|
||||
|
||||
while (count != 0)
|
||||
{
|
||||
int new_index, new_trailing;
|
||||
gboolean split_cursor;
|
||||
gboolean strong;
|
||||
|
||||
g_object_get (gtk_widget_get_settings (GTK_WIDGET (self)),
|
||||
"gtk-split-cursor", &split_cursor,
|
||||
NULL);
|
||||
|
||||
if (split_cursor)
|
||||
strong = TRUE;
|
||||
else
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GdkSeat *seat;
|
||||
GdkDevice *keyboard = NULL;
|
||||
PangoDirection direction = PANGO_DIRECTION_LTR;
|
||||
|
||||
display = gtk_widget_get_display (GTK_WIDGET (self));
|
||||
seat = gdk_display_get_default_seat (display);
|
||||
if (seat)
|
||||
keyboard = gdk_seat_get_keyboard (seat);
|
||||
if (keyboard)
|
||||
direction = gdk_device_get_direction (keyboard);
|
||||
|
||||
strong = direction == priv->resolved_dir;
|
||||
}
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
@@ -5098,11 +5099,11 @@ gtk_text_move_visually (GtkText *self,
|
||||
index = 0;
|
||||
else if (new_index != G_MAXINT)
|
||||
index = new_index;
|
||||
|
||||
|
||||
while (new_trailing--)
|
||||
index = g_utf8_next_char (text + index) - text;
|
||||
}
|
||||
|
||||
|
||||
return g_utf8_pointer_to_offset (text, text + index);
|
||||
}
|
||||
|
||||
|
@@ -387,6 +387,9 @@ _gtk_text_attributes_fill_from_tags (GtkTextAttributes *dest,
|
||||
if (tag->priv->pixels_inside_wrap_set)
|
||||
dest->pixels_inside_wrap = vals->pixels_inside_wrap;
|
||||
|
||||
if (tag->priv->line_spacing_set)
|
||||
dest->line_spacing = vals->line_spacing;
|
||||
|
||||
if (tag->priv->tabs_set)
|
||||
{
|
||||
if (dest->tabs)
|
||||
@@ -457,6 +460,7 @@ _gtk_text_tag_affects_size (GtkTextTag *tag)
|
||||
priv->pixels_above_lines_set ||
|
||||
priv->pixels_below_lines_set ||
|
||||
priv->pixels_inside_wrap_set ||
|
||||
priv->line_spacing_set ||
|
||||
priv->tabs_set ||
|
||||
priv->underline_set ||
|
||||
priv->overline_set ||
|
||||
|
@@ -147,6 +147,8 @@ struct _GtkTextAttributes
|
||||
int pixels_below_lines;
|
||||
int pixels_inside_wrap;
|
||||
|
||||
float line_spacing;
|
||||
|
||||
int letter_spacing;
|
||||
|
||||
guint invisible : 1;
|
||||
|
@@ -1277,6 +1277,8 @@ set_para_values (GtkTextLayout *layout,
|
||||
pango_layout_set_spacing (display->layout,
|
||||
style->pixels_inside_wrap * PANGO_SCALE);
|
||||
|
||||
pango_layout_set_line_spacing (display->layout, style->line_spacing);
|
||||
|
||||
if (style->tabs)
|
||||
pango_layout_set_tabs (display->layout, style->tabs);
|
||||
|
||||
|
@@ -107,6 +107,7 @@ enum {
|
||||
PROP_PIXELS_ABOVE_LINES,
|
||||
PROP_PIXELS_BELOW_LINES,
|
||||
PROP_PIXELS_INSIDE_WRAP,
|
||||
PROP_LINE_SPACING,
|
||||
PROP_EDITABLE,
|
||||
PROP_WRAP_MODE,
|
||||
PROP_JUSTIFICATION,
|
||||
@@ -150,6 +151,7 @@ enum {
|
||||
PROP_PIXELS_ABOVE_LINES_SET,
|
||||
PROP_PIXELS_BELOW_LINES_SET,
|
||||
PROP_PIXELS_INSIDE_WRAP_SET,
|
||||
PROP_LINE_SPACING_SET,
|
||||
PROP_EDITABLE_SET,
|
||||
PROP_WRAP_MODE_SET,
|
||||
PROP_JUSTIFICATION_SET,
|
||||
@@ -585,6 +587,8 @@ gtk_text_tag_class_init (GtkTextTagClass *klass)
|
||||
* GtkTextTag:pixels-inside-wrap:
|
||||
*
|
||||
* Pixels of blank space between wrapped lines in a paragraph.
|
||||
*
|
||||
* Ignored if line-spacing is set.
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PIXELS_INSIDE_WRAP,
|
||||
@@ -596,6 +600,21 @@ gtk_text_tag_class_init (GtkTextTagClass *klass)
|
||||
0,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkTexTag:line-spacing:
|
||||
*
|
||||
* The line spacing factor that is applied between consecutive lines.
|
||||
*
|
||||
* Since: 4.4
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_LINE_SPACING,
|
||||
g_param_spec_float ("line-spacing",
|
||||
P_("Line spacing"),
|
||||
P_("The factor for spacing between lines"),
|
||||
0.0, 10.0, 0.0,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkTextTag:strikethrough:
|
||||
*
|
||||
@@ -936,6 +955,10 @@ gtk_text_tag_class_init (GtkTextTagClass *klass)
|
||||
P_("Pixels inside wrap set"),
|
||||
P_("Whether this tag affects the number of pixels between wrapped lines"));
|
||||
|
||||
ADD_SET_PROP ("line-spacing-set", PROP_LINE_SPACING_SET,
|
||||
P_("Linespacing set"),
|
||||
P_("Whether this tag affects spacing between wrapped lines"));
|
||||
|
||||
ADD_SET_PROP ("strikethrough-set", PROP_STRIKETHROUGH_SET,
|
||||
P_("Strikethrough set"),
|
||||
P_("Whether this tag affects strikethrough"));
|
||||
@@ -1573,6 +1596,13 @@ gtk_text_tag_set_property (GObject *object,
|
||||
size_changed = TRUE;
|
||||
break;
|
||||
|
||||
case PROP_LINE_SPACING:
|
||||
priv->line_spacing_set = TRUE;
|
||||
priv->values->line_spacing = g_value_get_float (value);
|
||||
g_object_notify (object, "line-spacing-set");
|
||||
size_changed = TRUE;
|
||||
break;
|
||||
|
||||
case PROP_EDITABLE:
|
||||
priv->editable_set = TRUE;
|
||||
priv->values->editable = g_value_get_boolean (value);
|
||||
@@ -2022,6 +2052,10 @@ gtk_text_tag_get_property (GObject *object,
|
||||
g_value_set_int (value, priv->values->pixels_inside_wrap);
|
||||
break;
|
||||
|
||||
case PROP_LINE_SPACING:
|
||||
g_value_set_float (value, priv->values->line_spacing);
|
||||
break;
|
||||
|
||||
case PROP_EDITABLE:
|
||||
g_value_set_boolean (value, priv->values->editable);
|
||||
break;
|
||||
@@ -2169,6 +2203,10 @@ gtk_text_tag_get_property (GObject *object,
|
||||
g_value_set_boolean (value, priv->pixels_inside_wrap_set);
|
||||
break;
|
||||
|
||||
case PROP_LINE_SPACING_SET:
|
||||
g_value_set_boolean (value, priv->line_spacing_set);
|
||||
break;
|
||||
|
||||
case PROP_EDITABLE_SET:
|
||||
g_value_set_boolean (value, priv->editable_set);
|
||||
break;
|
||||
|
@@ -71,6 +71,7 @@ struct _GtkTextTagPrivate
|
||||
guint pixels_above_lines_set : 1;
|
||||
guint pixels_below_lines_set : 1;
|
||||
guint pixels_inside_wrap_set : 1;
|
||||
guint line_spacing_set : 1;
|
||||
guint tabs_set : 1;
|
||||
guint underline_set : 1;
|
||||
guint overline_set : 1;
|
||||
|
@@ -57,6 +57,8 @@
|
||||
#include "gtknative.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkjoinedmenuprivate.h"
|
||||
#include "gtkcssstylepropertyprivate.h"
|
||||
#include "gtkcssstringvalueprivate.h"
|
||||
|
||||
/**
|
||||
* GtkTextView:
|
||||
@@ -7659,6 +7661,11 @@ gtk_text_view_set_attributes_from_style (GtkTextView *text_view,
|
||||
pango_font_description_free (values->font);
|
||||
|
||||
values->font = gtk_css_style_get_pango_font (style);
|
||||
|
||||
if (_gtk_css_value_equal (style->font->line_height, gtk_css_line_height_value_get_default ()))
|
||||
values->line_spacing = 0.0;
|
||||
else
|
||||
values->line_spacing = _gtk_css_number_value_get (style->font->line_height, 1.0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -441,8 +441,11 @@ testdata = [
|
||||
'treeview-fixed-height.css',
|
||||
'treeview-fixed-height.ref.ui',
|
||||
'treeview-fixed-height.ui',
|
||||
'treeview-headers-hidden.ref.ui',
|
||||
'treeview-headers-hidden.ui',
|
||||
# this test fails with an off-by-one in ci too frequently
|
||||
# to be left enabled. Remove it until somebody figures out
|
||||
# what is going on there.
|
||||
#'treeview-headers-hidden.ref.ui',
|
||||
#'treeview-headers-hidden.ui',
|
||||
'unresolvable.css',
|
||||
'unresolvable.ref.ui',
|
||||
'unresolvable.ui',
|
||||
|
Reference in New Issue
Block a user