Compare commits
129 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bb37613711 | |||
| 908ebf2b23 | |||
| 715dd26260 | |||
| 83d41b32e9 | |||
| 9bf52a274c | |||
| 4aae883fe8 | |||
| 2691e4e949 | |||
| 20d7b7f59b | |||
| 1fcd08d76a | |||
| 060a9f072c | |||
| 4a631787bd | |||
| 032473fef8 | |||
| 5dd8801ee5 | |||
| 5c9643b6eb | |||
| 4de670b0b4 | |||
| ade40a7a0c | |||
| 9926e6ebde | |||
| b930c5a8a2 | |||
| 7eb5dfd294 | |||
| 8752564fea | |||
| 988fac404a | |||
| 7a3eaad193 | |||
| 3fccb16ca6 | |||
| 2c38b71ca5 | |||
| 1c93bef0d5 | |||
| eea76e8cce | |||
| 3b604331ec | |||
| 92546cf9f7 | |||
| 3c9f9d598b | |||
| ed46053dc9 | |||
| a3db7437b3 | |||
| b2d639b6d9 | |||
| f1c7803f80 | |||
| c179fce6c7 | |||
| 795899f9d5 | |||
| 88ab3a6942 | |||
| 58e8dd1c0d | |||
| b8bbf7b63b | |||
| 05e28fb498 | |||
| c6d9963d1a | |||
| 2d3a902beb | |||
| 8b1f3936b6 | |||
| 108ea50179 | |||
| df1892c052 | |||
| 0820a79bf5 | |||
| 4427bde8a7 | |||
| dec4db5943 | |||
| fd7f6ca7ad | |||
| dea309144b | |||
| f1e4efebb7 | |||
| 0885eb0a7b | |||
| fc68d1b1e6 | |||
| b329090e69 | |||
| 6314ebd435 | |||
| e89e182565 | |||
| 552fe0406c | |||
| b062dea1aa | |||
| 9b561581d5 | |||
| 7f6c31c041 | |||
| 717c55c9aa | |||
| 7d1c6272be | |||
| 2f387c2a23 | |||
| 0d95c5dfe2 | |||
| f2a2908c59 | |||
| f4cb60dcca | |||
| b3d0629709 | |||
| 30f55c4d07 | |||
| f00d964f4f | |||
| d2920c501d | |||
| af528b08dc | |||
| a628907891 | |||
| 19ad4d67ef | |||
| a4e427b44a | |||
| 5b94e3c2f2 | |||
| 3278e9ab6c | |||
| 02d8e95b73 | |||
| e0b9b51e9f | |||
| fb06b7fa94 | |||
| 7b451678f5 | |||
| 3be9e819d6 | |||
| 758c54eab8 | |||
| c39cc15573 | |||
| 8999bb0b78 | |||
| 7a81b7c7be | |||
| e475d4bdc5 | |||
| 980a6a20b1 | |||
| 064ad42432 | |||
| 4ff9163c47 | |||
| 45ebe47d94 | |||
| 2803bd93ce | |||
| 51161fb0d6 | |||
| 63fd97749c | |||
| f2d736d2cc | |||
| 9b9a656e54 | |||
| 8f734b01b2 | |||
| 69250371b0 | |||
| 731613d70b | |||
| 5f21c45f75 | |||
| 8beea4d958 | |||
| 1583200e24 | |||
| 03fa8ed259 | |||
| 0bd939624e | |||
| b658a1a8e3 | |||
| 7eae9d115c | |||
| 2ca56d4c4c | |||
| f6d7967e96 | |||
| 9bddc0ff85 | |||
| 6e47ebe030 | |||
| 9728dabf12 | |||
| e904c49e8a | |||
| 27ddd39d69 | |||
| 86e907b088 | |||
| 8b46538af9 | |||
| 5910a28aa5 | |||
| 3935027880 | |||
| 8665828d7f | |||
| a8b559e99f | |||
| 5674a3db46 | |||
| dd3acc9014 | |||
| a9364bc053 | |||
| 59313e1459 | |||
| 3e54d374de | |||
| 9856218073 | |||
| 97cdf87350 | |||
| d8f91e7df9 | |||
| 91d4e2b3e3 | |||
| e5cccbf5a0 | |||
| 5cfe9ab603 | |||
| 01a6bbdc73 |
@@ -174,6 +174,7 @@
|
||||
<file>foreigndrawing.c</file>
|
||||
<file>font_features.c</file>
|
||||
<file>fontplane.c</file>
|
||||
<file>fontrendering.c</file>
|
||||
<file>gestures.c</file>
|
||||
<file>glarea.c</file>
|
||||
<file>headerbar.c</file>
|
||||
@@ -281,6 +282,9 @@
|
||||
<gresource prefix="/fixed">
|
||||
<file>fixed.css</file>
|
||||
</gresource>
|
||||
<gresource prefix="/fontrendering">
|
||||
<file>fontrendering.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/org/gtk/Demo4">
|
||||
<file>icons/16x16/actions/application-exit.png</file>
|
||||
<file>icons/16x16/actions/document-new.png</file>
|
||||
|
||||
@@ -0,0 +1,288 @@
|
||||
/* Pango/Font rendering
|
||||
*
|
||||
* Demonstrates various aspects of font rendering.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
static GtkWidget *font_button = NULL;
|
||||
static GtkWidget *entry = NULL;
|
||||
static GtkWidget *image = NULL;
|
||||
static GtkWidget *hinting = NULL;
|
||||
static GtkWidget *hint_metrics = NULL;
|
||||
static GtkWidget *up_button = NULL;
|
||||
static GtkWidget *down_button = NULL;
|
||||
static GtkWidget *text_radio = NULL;
|
||||
static GtkWidget *show_grid = NULL;
|
||||
static GtkWidget *show_extents = NULL;
|
||||
|
||||
static PangoContext *context;
|
||||
|
||||
static int scale = 10;
|
||||
|
||||
static void
|
||||
on_destroy (gpointer data)
|
||||
{
|
||||
window = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
update_image (void)
|
||||
{
|
||||
const char *text;
|
||||
PangoFontDescription *desc;
|
||||
PangoLayout *layout;
|
||||
PangoRectangle ink, pink, logical;
|
||||
int baseline;
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
GdkPixbuf *pixbuf;
|
||||
GdkPixbuf *pixbuf2;
|
||||
const char *hint;
|
||||
cairo_font_options_t *fopt;
|
||||
cairo_hint_style_t hintstyle;
|
||||
cairo_hint_metrics_t hintmetrics;
|
||||
int i;
|
||||
|
||||
if (!context)
|
||||
context = gtk_widget_create_pango_context (image);
|
||||
|
||||
text = gtk_editable_get_text (GTK_EDITABLE (entry));
|
||||
desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (font_button));
|
||||
|
||||
fopt = cairo_font_options_copy (pango_cairo_context_get_font_options (context));
|
||||
|
||||
hint = gtk_combo_box_get_active_id (GTK_COMBO_BOX (hinting));
|
||||
if (strcmp (hint, "none") == 0)
|
||||
hintstyle = CAIRO_HINT_STYLE_NONE;
|
||||
else if (strcmp (hint, "slight") == 0)
|
||||
hintstyle = CAIRO_HINT_STYLE_SLIGHT;
|
||||
else if (strcmp (hint, "medium") == 0)
|
||||
hintstyle = CAIRO_HINT_STYLE_MEDIUM;
|
||||
else if (strcmp (hint, "full") == 0)
|
||||
hintstyle = CAIRO_HINT_STYLE_FULL;
|
||||
else
|
||||
hintstyle = CAIRO_HINT_STYLE_DEFAULT;
|
||||
cairo_font_options_set_hint_style (fopt, hintstyle);
|
||||
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (hint_metrics)))
|
||||
hintmetrics = CAIRO_HINT_METRICS_ON;
|
||||
else
|
||||
hintmetrics = CAIRO_HINT_METRICS_OFF;
|
||||
cairo_font_options_set_hint_metrics (fopt, hintmetrics);
|
||||
|
||||
pango_cairo_context_set_font_options (context, fopt);
|
||||
cairo_font_options_destroy (fopt);
|
||||
pango_context_changed (context);
|
||||
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (text_radio)))
|
||||
{
|
||||
layout = pango_layout_new (context);
|
||||
pango_layout_set_font_description (layout, desc);
|
||||
pango_layout_set_text (layout, text, -1);
|
||||
pango_layout_get_extents (layout, &ink, &logical);
|
||||
pink = ink;
|
||||
baseline = pango_layout_get_baseline (layout);
|
||||
|
||||
pango_extents_to_pixels (&ink, NULL);
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, ink.width + 20, ink.height + 20);
|
||||
cr = cairo_create (surface);
|
||||
cairo_set_source_rgb (cr, 1, 1, 1);
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
cairo_move_to (cr, 10, 10);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
|
||||
cairo_destroy (cr);
|
||||
g_object_unref (layout);
|
||||
|
||||
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, cairo_image_surface_get_width (surface), cairo_image_surface_get_height (surface));
|
||||
pixbuf2 = gdk_pixbuf_scale_simple (pixbuf, gdk_pixbuf_get_width (pixbuf) * scale, gdk_pixbuf_get_height (pixbuf) * scale, GDK_INTERP_NEAREST);
|
||||
|
||||
g_object_unref (pixbuf);
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
surface = cairo_image_surface_create_for_data (gdk_pixbuf_get_pixels (pixbuf2),
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
gdk_pixbuf_get_width (pixbuf2),
|
||||
gdk_pixbuf_get_height (pixbuf2),
|
||||
gdk_pixbuf_get_rowstride (pixbuf2));
|
||||
|
||||
cr = cairo_create (surface);
|
||||
cairo_set_line_width (cr, 1);
|
||||
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_grid)))
|
||||
{
|
||||
cairo_set_source_rgba (cr, 0.2, 0, 0, 0.2);
|
||||
for (i = 1; i < ink.height + 20; i++)
|
||||
{
|
||||
cairo_move_to (cr, 0, scale * i - 0.5);
|
||||
cairo_line_to (cr, scale * (ink.width + 20), scale * i - 0.5);
|
||||
cairo_stroke (cr);
|
||||
}
|
||||
for (i = 1; i < ink.width + 20; i++)
|
||||
{
|
||||
cairo_move_to (cr, scale * i - 0.5, 0);
|
||||
cairo_line_to (cr, scale * i - 0.5, scale * (ink.height + 20));
|
||||
cairo_stroke (cr);
|
||||
}
|
||||
}
|
||||
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_extents)))
|
||||
{
|
||||
cairo_set_source_rgba (cr, 0, 0, 1, 1);
|
||||
|
||||
cairo_rectangle (cr,
|
||||
scale * (10 + pango_units_to_double (logical.x)) - 0.5,
|
||||
scale * (10 + pango_units_to_double (logical.y)) - 0.5,
|
||||
scale * pango_units_to_double (logical.width) + 1,
|
||||
scale * pango_units_to_double (logical.height) + 1);
|
||||
cairo_stroke (cr);
|
||||
cairo_move_to (cr, scale * (10 + pango_units_to_double (logical.x)) - 0.5,
|
||||
scale * (10 + pango_units_to_double (baseline)) - 0.5);
|
||||
cairo_line_to (cr, scale * (10 + pango_units_to_double (logical.x + logical.width)) + 1,
|
||||
scale * (10 + pango_units_to_double (baseline)) - 0.5);
|
||||
cairo_stroke (cr);
|
||||
cairo_set_source_rgba (cr, 1, 0, 0, 1);
|
||||
cairo_rectangle (cr,
|
||||
scale * (10 + pango_units_to_double (pink.x)) + 0.5,
|
||||
scale * (10 + pango_units_to_double (pink.y)) + 0.5,
|
||||
scale * pango_units_to_double (pink.width) - 1,
|
||||
scale * pango_units_to_double (pink.height) - 1);
|
||||
cairo_stroke (cr);
|
||||
}
|
||||
|
||||
cairo_surface_destroy (surface);
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
else
|
||||
{
|
||||
PangoLayoutIter *iter;
|
||||
PangoLayoutRun *run;
|
||||
PangoGlyphInfo *g;
|
||||
int i, j;
|
||||
|
||||
layout = pango_layout_new (context);
|
||||
pango_layout_set_font_description (layout, desc);
|
||||
pango_layout_set_text (layout, "aaaa", -1);
|
||||
pango_layout_get_extents (layout, &ink, &logical);
|
||||
pango_extents_to_pixels (&logical, NULL);
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, logical.width * 3 / 2, 4*logical.height);
|
||||
cr = cairo_create (surface);
|
||||
cairo_set_source_rgb (cr, 1, 1, 1);
|
||||
cairo_paint (cr);
|
||||
|
||||
iter = pango_layout_get_iter (layout);
|
||||
run = pango_layout_iter_get_run (iter);
|
||||
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
g = &(run->glyphs->glyphs[i]);
|
||||
g->geometry.width = PANGO_UNITS_ROUND (g->geometry.width * 3 / 2);
|
||||
}
|
||||
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
g = &(run->glyphs->glyphs[i]);
|
||||
g->geometry.x_offset = i * (PANGO_SCALE / 4);
|
||||
g->geometry.y_offset = j * (PANGO_SCALE / 4);
|
||||
}
|
||||
|
||||
cairo_move_to (cr, 0, j * logical.height);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
}
|
||||
|
||||
cairo_destroy (cr);
|
||||
pango_layout_iter_free (iter);
|
||||
g_object_unref (layout);
|
||||
|
||||
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, cairo_image_surface_get_width (surface), cairo_image_surface_get_height (surface));
|
||||
pixbuf2 = gdk_pixbuf_scale_simple (pixbuf, gdk_pixbuf_get_width (pixbuf) * scale, gdk_pixbuf_get_height (pixbuf) * scale, GDK_INTERP_NEAREST);
|
||||
g_object_unref (pixbuf);
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
|
||||
gtk_picture_set_pixbuf (GTK_PICTURE (image), pixbuf2);
|
||||
|
||||
g_object_unref (pixbuf2);
|
||||
|
||||
pango_font_description_free (desc);
|
||||
}
|
||||
|
||||
static void
|
||||
update_buttons (void)
|
||||
{
|
||||
gtk_widget_set_sensitive (up_button, scale < 32);
|
||||
gtk_widget_set_sensitive (down_button, scale > 1);
|
||||
}
|
||||
|
||||
static void
|
||||
scale_up (void)
|
||||
{
|
||||
scale += 1;
|
||||
update_buttons ();
|
||||
update_image ();
|
||||
}
|
||||
|
||||
static void
|
||||
scale_down (void)
|
||||
{
|
||||
scale -= 1;
|
||||
update_buttons ();
|
||||
update_image ();
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_fontrendering (GtkWidget *do_widget)
|
||||
{
|
||||
if (!window)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/fontrendering/fontrendering.ui");
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (on_destroy), NULL);
|
||||
g_object_set_data_full (G_OBJECT (window), "builder", builder, g_object_unref);
|
||||
font_button = GTK_WIDGET (gtk_builder_get_object (builder, "font_button"));
|
||||
up_button = GTK_WIDGET (gtk_builder_get_object (builder, "up_button"));
|
||||
down_button = GTK_WIDGET (gtk_builder_get_object (builder, "down_button"));
|
||||
entry = GTK_WIDGET (gtk_builder_get_object (builder, "entry"));
|
||||
image = GTK_WIDGET (gtk_builder_get_object (builder, "image"));
|
||||
hinting = GTK_WIDGET (gtk_builder_get_object (builder, "hinting"));
|
||||
hint_metrics = GTK_WIDGET (gtk_builder_get_object (builder, "hint_metrics"));
|
||||
text_radio = GTK_WIDGET (gtk_builder_get_object (builder, "text_radio"));
|
||||
show_grid = GTK_WIDGET (gtk_builder_get_object (builder, "show_grid"));
|
||||
show_extents = GTK_WIDGET (gtk_builder_get_object (builder, "show_extents"));
|
||||
|
||||
g_signal_connect (up_button, "clicked", G_CALLBACK (scale_up), NULL);
|
||||
g_signal_connect (down_button, "clicked", G_CALLBACK (scale_down), NULL);
|
||||
g_signal_connect (entry, "notify::text", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (font_button, "notify::font-desc", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (hinting, "notify::active", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (hint_metrics, "notify::active", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (text_radio, "notify::active", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (show_grid, "notify::active", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (show_extents, "notify::active", G_CALLBACK (update_image), NULL);
|
||||
|
||||
update_image ();
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkAdjustment" id="scale_adj">
|
||||
<property name="upper">24</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">4</property>
|
||||
</object>
|
||||
<object class="GtkWindow" id="window">
|
||||
<property name="default-width">600</property>
|
||||
<property name="default-height">300</property>
|
||||
<property name="title">Font rendering</property>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="margin-top">10</property>
|
||||
<property name="row-spacing">10</property>
|
||||
<property name="column-spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="margin-start">10</property>
|
||||
<property name="label">Text</property>
|
||||
<property name="xalign">1</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry">
|
||||
<property name="text">Fonts render</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="margin-start">10</property>
|
||||
<property name="label">Font</property>
|
||||
<property name="xalign">1</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFontButton" id="font_button">
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Hinting</property>
|
||||
<property name="xalign">1</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="left-attach">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="hinting">
|
||||
<property name="active">0</property>
|
||||
<property name="valign">center</property>
|
||||
<items>
|
||||
<item translatable="yes" id="none">None</item>
|
||||
<item translatable="yes" id="slight">Slight</item>
|
||||
<item translatable="yes" id="medium">Medium</item>
|
||||
<item translatable="yes" id="full">Full</item>
|
||||
</items>
|
||||
<layout>
|
||||
<property name="left-attach">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="hint_metrics">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Hint Metrics</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="left-attach">3</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="show_extents">
|
||||
<property name="active">1</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Show Extents</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="left-attach">4</property>
|
||||
<property name="top-attach">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="show_grid">
|
||||
<property name="active">1</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Show Grid</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="left-attach">4</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="up_button">
|
||||
<property name="icon-name">list-add-symbolic</property>
|
||||
<style>
|
||||
<class name="circular"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="left-attach">5</property>
|
||||
<property name="top-attach">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="down_button">
|
||||
<property name="icon-name">list-remove-symbolic</property>
|
||||
<style>
|
||||
<class name="circular"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="left-attach">5</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">1</property>
|
||||
<layout>
|
||||
<property name="left-attach">6</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<style><class name="linked"/></style>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="text_radio">
|
||||
<property name="draw-indicator">0</property>
|
||||
<property name="label">Text</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="grid_radio">
|
||||
<property name="draw-indicator">0</property>
|
||||
<property name="label">Grid</property>
|
||||
<property name="group">text_radio</property>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">3</property>
|
||||
<property name="column-span">7</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="propagate-natural-height">1</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkPicture" id="image">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="can-shrink">0</property>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">4</property>
|
||||
<property name="column-span">7</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
@@ -202,7 +202,7 @@ languages_variant_init (const char *variant)
|
||||
else
|
||||
g_warning ("Failed to load '%s': %s\n", filename, error->message);
|
||||
|
||||
g_free (error);
|
||||
g_clear_error (&error);
|
||||
g_free (filename);
|
||||
g_free (buf);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ demos = files([
|
||||
'filtermodel.c',
|
||||
'fishbowl.c',
|
||||
'fixed.c',
|
||||
'fontrendering.c',
|
||||
'foreigndrawing.c',
|
||||
'gestures.c',
|
||||
'glarea.c',
|
||||
|
||||
@@ -3435,6 +3435,7 @@ bad things might happen.</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="icon-name">emblem-system-symbolic</property>
|
||||
<property name="menu-model">gear_menu</property>
|
||||
<property name="tooltip-text">This is a menu button</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">3</property>
|
||||
|
||||
@@ -11,7 +11,10 @@ GTK is released under the GNU Library General Public License
|
||||
applications. GTK has a C-based object-oriented architecture that
|
||||
allows for maximum flexibility. Bindings for many other languages have
|
||||
been written, including C++, Objective-C, Guile/Scheme, Perl, Python,
|
||||
TOM, Ada95, Free Pascal, and Eiffel.
|
||||
TOM, Ada95, Free Pascal, and Eiffel. The GTK library itself contains
|
||||
<firstterm>widgets</firstterm>, that is, GUI components such as GtkButton
|
||||
or GtkTextView.
|
||||
|
||||
</para>
|
||||
<para>
|
||||
GTK depends on the following libraries:
|
||||
@@ -105,14 +108,6 @@ and rendering it using different rendering APIs. GSK provides renderers
|
||||
for OpenGL, Vulkan and cairo.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>GTK</term>
|
||||
<listitem><para>
|
||||
The GTK library itself contains <firstterm>widgets</firstterm>,
|
||||
that is, GUI components such as GtkButton or GtkTextView.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
</partintro>
|
||||
|
||||
@@ -98,7 +98,9 @@ _gdk_broadway_display_size_changed (GdkDisplay *display,
|
||||
GdkBroadwaySurface *toplevel = l->data;
|
||||
|
||||
if (toplevel->maximized)
|
||||
gdk_surface_move_resize (GDK_SURFACE (toplevel), 0, 0, msg->width, msg->height);
|
||||
gdk_broadway_surface_move_resize (GDK_SURFACE (toplevel),
|
||||
0, 0,
|
||||
msg->width, msg->height);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,12 @@ void _gdk_broadway_surface_grab_check_unmap (GdkSurface *surface,
|
||||
gulong serial);
|
||||
void gdk_broadway_surface_update_popups (GdkSurface *surface);
|
||||
|
||||
void gdk_broadway_surface_move_resize (GdkSurface *surface,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
void _gdk_keymap_keys_changed (GdkDisplay *display);
|
||||
gint _gdk_broadway_get_group_for_state (GdkDisplay *display,
|
||||
GdkModifierType state);
|
||||
|
||||
@@ -368,12 +368,12 @@ gdk_broadway_surface_withdraw (GdkSurface *surface)
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_surface_move_resize (GdkSurface *surface,
|
||||
gboolean with_move,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
gdk_broadway_surface_move_resize_internal (GdkSurface *surface,
|
||||
gboolean with_move,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
GdkBroadwaySurface *impl = GDK_BROADWAY_SURFACE (surface);
|
||||
GdkBroadwayDisplay *broadway_display;
|
||||
@@ -424,6 +424,84 @@ gdk_broadway_surface_move_resize (GdkSurface *surface,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gdk_broadway_surface_move_resize (GdkSurface *surface,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
gdk_broadway_surface_move_resize_internal (surface, TRUE,
|
||||
x, y,
|
||||
width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_surface_toplevel_resize (GdkSurface *surface,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
gdk_broadway_surface_move_resize_internal (surface, FALSE,
|
||||
0, 0,
|
||||
width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_surface_move (GdkSurface *surface,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
gdk_broadway_surface_move_resize_internal (surface, TRUE, x, y, -1, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_surface_moved_to_rect (GdkSurface *surface,
|
||||
GdkRectangle final_rect)
|
||||
{
|
||||
GdkSurface *toplevel;
|
||||
int x, y;
|
||||
|
||||
if (surface->surface_type == GDK_SURFACE_POPUP)
|
||||
toplevel = surface->parent;
|
||||
else
|
||||
toplevel = surface->transient_for;
|
||||
|
||||
gdk_surface_get_origin (toplevel, &x, &y);
|
||||
x += final_rect.x;
|
||||
y += final_rect.y;
|
||||
|
||||
if (final_rect.width != surface->width ||
|
||||
final_rect.height != surface->height)
|
||||
{
|
||||
gdk_broadway_surface_move_resize (surface,
|
||||
x, y,
|
||||
final_rect.width, final_rect.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
gdk_broadway_surface_move (surface, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_surface_move_to_rect (GdkSurface *surface,
|
||||
const GdkRectangle *rect,
|
||||
GdkGravity rect_anchor,
|
||||
GdkGravity surface_anchor,
|
||||
GdkAnchorHints anchor_hints,
|
||||
gint rect_anchor_dx,
|
||||
gint rect_anchor_dy)
|
||||
{
|
||||
gdk_surface_move_to_rect_helper (surface,
|
||||
rect,
|
||||
rect_anchor,
|
||||
surface_anchor,
|
||||
anchor_hints,
|
||||
rect_anchor_dx,
|
||||
rect_anchor_dy,
|
||||
gdk_broadway_surface_moved_to_rect);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_surface_raise (GdkSurface *surface)
|
||||
{
|
||||
@@ -695,9 +773,9 @@ gdk_broadway_surface_maximize (GdkSurface *surface)
|
||||
monitor = gdk_display_get_primary_monitor (display);
|
||||
gdk_monitor_get_geometry (monitor, &geom);
|
||||
|
||||
gdk_surface_move_resize (surface,
|
||||
geom.x, geom.y,
|
||||
geom.width, geom.height);
|
||||
gdk_broadway_surface_move_resize (surface,
|
||||
geom.x, geom.y,
|
||||
geom.width, geom.height);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -718,11 +796,11 @@ gdk_broadway_surface_unmaximize (GdkSurface *surface)
|
||||
|
||||
gdk_synthesize_surface_state (surface, GDK_SURFACE_STATE_MAXIMIZED, 0);
|
||||
|
||||
gdk_surface_move_resize (surface,
|
||||
impl->pre_maximize_x,
|
||||
impl->pre_maximize_y,
|
||||
impl->pre_maximize_width,
|
||||
impl->pre_maximize_height);
|
||||
gdk_broadway_surface_move_resize (surface,
|
||||
impl->pre_maximize_x,
|
||||
impl->pre_maximize_y,
|
||||
impl->pre_maximize_width,
|
||||
impl->pre_maximize_height);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -813,7 +891,9 @@ gdk_broadway_surface_update_popups (GdkSurface *parent)
|
||||
int new_y = parent->y + popup_impl->offset_y;
|
||||
|
||||
if (new_x != popup->x || new_y != popup->y)
|
||||
gdk_broadway_surface_move_resize (popup, TRUE, new_x, new_y, popup->width, popup->height);
|
||||
gdk_broadway_surface_move_resize (popup,
|
||||
new_x, new_y,
|
||||
popup->width, popup->height);
|
||||
gdk_broadway_surface_restack_toplevel (popup, parent, TRUE);
|
||||
}
|
||||
}
|
||||
@@ -935,7 +1015,8 @@ update_pos (MoveResizeData *mv_resize,
|
||||
w, h, &w, &h);
|
||||
}
|
||||
|
||||
gdk_surface_move_resize (mv_resize->moveresize_surface, x, y, w, h);
|
||||
gdk_broadway_surface_move_resize (mv_resize->moveresize_surface,
|
||||
x, y, w, h);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -944,7 +1025,7 @@ update_pos (MoveResizeData *mv_resize,
|
||||
x = mv_resize->moveresize_orig_x + dx;
|
||||
y = mv_resize->moveresize_orig_y + dy;
|
||||
|
||||
gdk_surface_move (mv_resize->moveresize_surface, x, y);
|
||||
gdk_broadway_surface_move (mv_resize->moveresize_surface, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1311,7 +1392,8 @@ gdk_broadway_surface_class_init (GdkBroadwaySurfaceClass *klass)
|
||||
impl_class->raise = gdk_broadway_surface_raise;
|
||||
impl_class->lower = gdk_broadway_surface_lower;
|
||||
impl_class->restack_toplevel = gdk_broadway_surface_restack_toplevel;
|
||||
impl_class->move_resize = gdk_broadway_surface_move_resize;
|
||||
impl_class->toplevel_resize = gdk_broadway_surface_toplevel_resize;
|
||||
impl_class->move_to_rect = gdk_broadway_surface_move_to_rect;
|
||||
impl_class->get_geometry = gdk_broadway_surface_get_geometry;
|
||||
impl_class->get_root_coords = gdk_broadway_surface_get_root_coords;
|
||||
impl_class->get_device_state = gdk_broadway_surface_get_device_state;
|
||||
|
||||
@@ -264,16 +264,6 @@ void gdk_surface_get_geometry (GdkSurface *surface,
|
||||
gint *width,
|
||||
gint *height);
|
||||
|
||||
void gdk_surface_move (GdkSurface *surface,
|
||||
gint x,
|
||||
gint y);
|
||||
|
||||
void gdk_surface_move_resize (GdkSurface *surface,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
GdkGLContext *gdk_surface_get_shared_data_gl_context (GdkSurface *surface);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
+13
-94
@@ -246,14 +246,15 @@ maybe_flip_position (gint bounds_pos,
|
||||
return primary;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_surface_real_move_to_rect (GdkSurface *surface,
|
||||
const GdkRectangle *rect,
|
||||
GdkGravity rect_anchor,
|
||||
GdkGravity surface_anchor,
|
||||
GdkAnchorHints anchor_hints,
|
||||
gint rect_anchor_dx,
|
||||
gint rect_anchor_dy)
|
||||
void
|
||||
gdk_surface_move_to_rect_helper (GdkSurface *surface,
|
||||
const GdkRectangle *rect,
|
||||
GdkGravity rect_anchor,
|
||||
GdkGravity surface_anchor,
|
||||
GdkAnchorHints anchor_hints,
|
||||
gint rect_anchor_dx,
|
||||
gint rect_anchor_dy,
|
||||
GdkSurfaceMovedToRect moved_to_rect)
|
||||
{
|
||||
GdkSurface *toplevel;
|
||||
GdkDisplay *display;
|
||||
@@ -362,17 +363,14 @@ gdk_surface_real_move_to_rect (GdkSurface *surface,
|
||||
final_rect.width += surface->shadow_left + surface->shadow_right;
|
||||
final_rect.height += surface->shadow_top + surface->shadow_bottom;
|
||||
|
||||
if (final_rect.width != surface->width || final_rect.height != surface->height)
|
||||
gdk_surface_move_resize (surface, final_rect.x, final_rect.y, final_rect.width, final_rect.height);
|
||||
else
|
||||
gdk_surface_move (surface, final_rect.x, final_rect.y);
|
||||
|
||||
gdk_surface_get_origin (toplevel, &x, &y);
|
||||
final_rect.x -= x;
|
||||
final_rect.y -= y;
|
||||
flipped_rect.x -= x;
|
||||
flipped_rect.y -= y;
|
||||
|
||||
moved_to_rect (surface, final_rect);
|
||||
|
||||
g_signal_emit_by_name (surface,
|
||||
"moved-to-rect",
|
||||
&flipped_rect,
|
||||
@@ -411,7 +409,6 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
|
||||
object_class->get_property = gdk_surface_get_property;
|
||||
|
||||
klass->beep = gdk_surface_real_beep;
|
||||
klass->move_to_rect = gdk_surface_real_move_to_rect;
|
||||
|
||||
/**
|
||||
* GdkSurface:cursor:
|
||||
@@ -2072,59 +2069,6 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
GDK_SURFACE_GET_CLASS (surface)->hide (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_surface_move_resize_toplevel (GdkSurface *surface,
|
||||
gboolean with_move,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
GDK_SURFACE_GET_CLASS (surface)->move_resize (surface, with_move, x, y, width, height);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gdk_surface_move_resize_internal (GdkSurface *surface,
|
||||
gboolean with_move,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_SURFACE (surface));
|
||||
|
||||
if (surface->destroyed)
|
||||
return;
|
||||
|
||||
gdk_surface_move_resize_toplevel (surface, with_move, x, y, width, height);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* gdk_surface_move:
|
||||
* @surface: a #GdkSurface
|
||||
* @x: X coordinate relative to surface’s parent
|
||||
* @y: Y coordinate relative to surface’s parent
|
||||
*
|
||||
* Repositions a surface relative to its parent surface.
|
||||
* For toplevel surfaces, window managers may ignore or modify the move;
|
||||
* you should probably use gtk_window_move() on a #GtkWindow widget
|
||||
* anyway, instead of using GDK functions. For child surfaces,
|
||||
* the move will reliably succeed.
|
||||
*
|
||||
* If you’re also planning to resize the surface, use gdk_surface_move_resize()
|
||||
* to both move and resize simultaneously, for a nicer visual effect.
|
||||
**/
|
||||
void
|
||||
gdk_surface_move (GdkSurface *surface,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
gdk_surface_move_resize_internal (surface, TRUE, x, y, -1, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_surface_resize:
|
||||
* @surface: a #GdkSurface
|
||||
@@ -2142,31 +2086,7 @@ gdk_surface_resize (GdkSurface *surface,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
gdk_surface_move_resize_internal (surface, FALSE, 0, 0, width, height);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* gdk_surface_move_resize:
|
||||
* @surface: a #GdkSurface
|
||||
* @x: new X position relative to surface’s parent
|
||||
* @y: new Y position relative to surface’s parent
|
||||
* @width: new width
|
||||
* @height: new height
|
||||
*
|
||||
* Equivalent to calling gdk_surface_move() and gdk_surface_resize(),
|
||||
* except that both operations are performed at once, avoiding strange
|
||||
* visual effects. (i.e. the user may be able to see the surface first
|
||||
* move, then resize, if you don’t use gdk_surface_move_resize().)
|
||||
**/
|
||||
void
|
||||
gdk_surface_move_resize (GdkSurface *surface,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
gdk_surface_move_resize_internal (surface, TRUE, x, y, width, height);
|
||||
GDK_SURFACE_GET_CLASS (surface)->toplevel_resize (surface, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2963,8 +2883,7 @@ gdk_surface_set_modal_hint (GdkSurface *surface,
|
||||
* this is to constrain user resizing, but the windowing system
|
||||
* will typically (but is not required to) also constrain the
|
||||
* current size of the surface to the provided values and
|
||||
* constrain programatic resizing via gdk_surface_resize() or
|
||||
* gdk_surface_move_resize().
|
||||
* constrain programatic resizing via gdk_surface_resize().
|
||||
*
|
||||
* Note that on X11, this effect has no effect on surfaces
|
||||
* of type %GDK_SURFACE_TEMP since these surfaces are not resizable
|
||||
|
||||
+14
-4
@@ -113,10 +113,7 @@ struct _GdkSurfaceClass
|
||||
GdkSurface *sibling,
|
||||
gboolean above);
|
||||
|
||||
void (* move_resize) (GdkSurface *surface,
|
||||
gboolean with_move,
|
||||
gint x,
|
||||
gint y,
|
||||
void (* toplevel_resize) (GdkSurface *surface,
|
||||
gint width,
|
||||
gint height);
|
||||
void (* move_to_rect) (GdkSurface *surface,
|
||||
@@ -258,6 +255,19 @@ struct _GdkSurfaceClass
|
||||
void gdk_surface_set_state (GdkSurface *surface,
|
||||
GdkSurfaceState new_state);
|
||||
|
||||
typedef void (* GdkSurfaceMovedToRect) (GdkSurface *surface,
|
||||
GdkRectangle final_rect);
|
||||
|
||||
void
|
||||
gdk_surface_move_to_rect_helper (GdkSurface *surface,
|
||||
const GdkRectangle *rect,
|
||||
GdkGravity rect_anchor,
|
||||
GdkGravity surface_anchor,
|
||||
GdkAnchorHints anchor_hints,
|
||||
gint rect_anchor_dx,
|
||||
gint rect_anchor_dy,
|
||||
GdkSurfaceMovedToRect moved_to_rect);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_SURFACE_PRIVATE_H__ */
|
||||
|
||||
@@ -1237,24 +1237,61 @@ window_quartz_move_resize (GdkSurface *window,
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_surface_quartz_move_resize (GdkSurface *window,
|
||||
gboolean with_move,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
gdk_surface_quartz_toplevel_resize (GdkSurface *surface,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
if (with_move && (width < 0 && height < 0))
|
||||
window_quartz_move (window, x, y);
|
||||
window_quartz_resize (window, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_surface_moved_to_rect (GdkSurface *surface,
|
||||
GdkRectangle final_rect)
|
||||
{
|
||||
GdkSurface *toplevel;
|
||||
int x, y;
|
||||
|
||||
if (surface->surface_type == GDK_SURFACE_POPUP)
|
||||
toplevel = surface->parent;
|
||||
else
|
||||
toplevel = surface->transient_for;
|
||||
|
||||
gdk_surface_get_origin (toplevel, &x, &y);
|
||||
x += final_rect.x;
|
||||
y += final_rect.y;
|
||||
|
||||
if (final_rect.width != surface->width ||
|
||||
final_rect.height != surface->height)
|
||||
{
|
||||
window_quartz_move_resize (surface,
|
||||
x, y,
|
||||
final_rect.width, final_rect.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (with_move)
|
||||
window_quartz_move_resize (window, x, y, width, height);
|
||||
else
|
||||
window_quartz_resize (window, width, height);
|
||||
window_quartz_resize (surface, final_rect.width, final_rect.height);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_surface_move_to_rect (GdkSurface *surface,
|
||||
const GdkRectangle *rect,
|
||||
GdkGravity rect_anchor,
|
||||
GdkGravity surface_anchor,
|
||||
GdkAnchorHints anchor_hints,
|
||||
gint rect_anchor_dx,
|
||||
gint rect_anchor_dy)
|
||||
{
|
||||
gdk_surface_move_to_rect_helper (surface,
|
||||
rect,
|
||||
rect_anchor,
|
||||
surface_anchor,
|
||||
anchor_hints,
|
||||
rect_anchor_dx,
|
||||
rect_anchor_dy,
|
||||
gdk_quartz_surface_moved_to_rect);
|
||||
}
|
||||
|
||||
/* Get the toplevel ordering from NSApp and update our own list. We do
|
||||
* this on demand since the NSApp’s list is not up to date directly
|
||||
* after we get windowDidBecomeMain.
|
||||
@@ -2641,7 +2678,8 @@ gdk_surface_impl_quartz_class_init (GdkSurfaceImplQuartzClass *klass)
|
||||
impl_class->raise = gdk_surface_quartz_raise;
|
||||
impl_class->lower = gdk_surface_quartz_lower;
|
||||
impl_class->restack_toplevel = gdk_surface_quartz_restack_toplevel;
|
||||
impl_class->move_resize = gdk_surface_quartz_move_resize;
|
||||
impl_class->toplevel_resize = gdk_surface_quartz_toplevel_resize;
|
||||
impl_class->move_to_rect = gdk_surface_quartz_move_to_rect;
|
||||
impl_class->get_geometry = gdk_surface_quartz_get_geometry;
|
||||
impl_class->get_root_coords = gdk_surface_quartz_get_root_coords;
|
||||
impl_class->get_device_state = gdk_surface_quartz_get_device_state;
|
||||
|
||||
@@ -93,6 +93,7 @@
|
||||
|
||||
#define GTK_SHELL1_VERSION 2
|
||||
#define OUTPUT_VERSION_WITH_DONE 2
|
||||
#define NO_XDG_OUTPUT_DONE_SINCE_VERSION 3
|
||||
|
||||
static void _gdk_wayland_display_load_cursor_theme (GdkWaylandDisplay *display_wayland);
|
||||
|
||||
@@ -531,7 +532,7 @@ gdk_registry_handle_global (void *data,
|
||||
}
|
||||
else if (strcmp(interface, "zxdg_output_manager_v1") == 0)
|
||||
{
|
||||
display_wayland->xdg_output_manager_version = MIN (version, 2);
|
||||
display_wayland->xdg_output_manager_version = MIN (version, 3);
|
||||
display_wayland->xdg_output_manager =
|
||||
wl_registry_bind (display_wayland->wl_registry, id,
|
||||
&zxdg_output_manager_v1_interface,
|
||||
@@ -2217,6 +2218,9 @@ should_update_monitor (GdkWaylandMonitor *monitor)
|
||||
static void
|
||||
apply_monitor_change (GdkWaylandMonitor *monitor)
|
||||
{
|
||||
GdkDisplay *display = GDK_MONITOR (monitor)->display;
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("monitor %d changed position %d %d, size %d %d",
|
||||
monitor->id,
|
||||
@@ -2227,7 +2231,11 @@ apply_monitor_change (GdkWaylandMonitor *monitor)
|
||||
gdk_monitor_set_size (GDK_MONITOR (monitor), monitor->width, monitor->height);
|
||||
gdk_monitor_set_connector (GDK_MONITOR (monitor), monitor->name);
|
||||
monitor->wl_output_done = FALSE;
|
||||
monitor->xdg_output_done = FALSE;
|
||||
/* xdg_output v3 marks xdg_output.done as deprecated, so if using
|
||||
* that version, no need to wait for xdg-output.done event.
|
||||
*/
|
||||
monitor->xdg_output_done =
|
||||
(display_wayland->xdg_output_manager_version >= NO_XDG_OUTPUT_DONE_SINCE_VERSION);
|
||||
|
||||
update_scale (GDK_MONITOR (monitor)->display);
|
||||
}
|
||||
|
||||
@@ -150,9 +150,20 @@ struct _GdkWaylandSurface
|
||||
} pending_move_to_rect;
|
||||
|
||||
struct {
|
||||
int width;
|
||||
int height;
|
||||
GdkSurfaceState state;
|
||||
struct {
|
||||
int width;
|
||||
int height;
|
||||
GdkSurfaceState state;
|
||||
} toplevel;
|
||||
|
||||
struct {
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
} popup;
|
||||
|
||||
uint32_t serial;
|
||||
} pending;
|
||||
|
||||
struct {
|
||||
@@ -170,10 +181,12 @@ struct _GdkWaylandSurfaceClass
|
||||
GdkSurfaceClass parent_class;
|
||||
};
|
||||
|
||||
static void gdk_wayland_surface_maybe_configure (GdkSurface *surface,
|
||||
int width,
|
||||
int height,
|
||||
int scale);
|
||||
static void gdk_wayland_surface_maybe_resize (GdkSurface *surface,
|
||||
int width,
|
||||
int height,
|
||||
int scale);
|
||||
|
||||
static void gdk_wayland_surface_configure (GdkSurface *surface);
|
||||
|
||||
static void maybe_set_gtk_surface_dbus_properties (GdkSurface *surface);
|
||||
static void maybe_set_gtk_surface_modal (GdkSurface *surface);
|
||||
@@ -184,6 +197,12 @@ static void gdk_wayland_surface_sync_opaque_region (GdkSurface *surface);
|
||||
|
||||
static void unset_transient_for_exported (GdkSurface *surface);
|
||||
|
||||
static void gdk_wayland_surface_move_resize (GdkSurface *surface,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
static void calculate_moved_to_rect_result (GdkSurface *surface,
|
||||
int x,
|
||||
int y,
|
||||
@@ -492,7 +511,9 @@ gdk_wayland_surface_update_scale (GdkSurface *surface)
|
||||
}
|
||||
|
||||
/* Notify app that scale changed */
|
||||
gdk_wayland_surface_maybe_configure (surface, surface->width, surface->height, scale);
|
||||
gdk_wayland_surface_maybe_resize (surface,
|
||||
surface->width, surface->height,
|
||||
scale);
|
||||
}
|
||||
|
||||
static void gdk_wayland_surface_create_surface (GdkSurface *surface);
|
||||
@@ -649,10 +670,10 @@ gdk_wayland_surface_finalize (GObject *object)
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_configure (GdkSurface *surface,
|
||||
int width,
|
||||
int height,
|
||||
int scale)
|
||||
gdk_wayland_surface_resize (GdkSurface *surface,
|
||||
int width,
|
||||
int height,
|
||||
int scale)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GdkEvent *event;
|
||||
@@ -702,10 +723,10 @@ static void gdk_wayland_surface_show (GdkSurface *surface,
|
||||
static void gdk_wayland_surface_hide (GdkSurface *surface);
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_maybe_configure (GdkSurface *surface,
|
||||
int width,
|
||||
int height,
|
||||
int scale)
|
||||
gdk_wayland_surface_maybe_resize (GdkSurface *surface,
|
||||
int width,
|
||||
int height,
|
||||
int scale)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
gboolean is_xdg_popup;
|
||||
@@ -728,7 +749,7 @@ gdk_wayland_surface_maybe_configure (GdkSurface *surface,
|
||||
if (is_xdg_popup && is_visible && !impl->initial_configure_received)
|
||||
gdk_wayland_surface_hide (surface);
|
||||
|
||||
gdk_wayland_surface_configure (surface, width, height, scale);
|
||||
gdk_wayland_surface_resize (surface, width, height, scale);
|
||||
|
||||
if (is_xdg_popup && is_visible && !impl->initial_configure_received)
|
||||
gdk_wayland_surface_show (surface, FALSE);
|
||||
@@ -1039,44 +1060,27 @@ gdk_wayland_surface_create_surface (GdkSurface *surface)
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_handle_configure (GdkSurface *surface,
|
||||
uint32_t serial)
|
||||
gdk_wayland_surface_configure_toplevel (GdkSurface *surface)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
GdkWaylandDisplay *display_wayland =
|
||||
GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
|
||||
GdkSurfaceState new_state;
|
||||
int width = impl->pending.width;
|
||||
int height = impl->pending.height;
|
||||
int width, height;
|
||||
gboolean fixed_size;
|
||||
gboolean saved_size;
|
||||
|
||||
if (!impl->initial_configure_received)
|
||||
{
|
||||
gdk_surface_thaw_updates (surface);
|
||||
impl->initial_configure_received = TRUE;
|
||||
}
|
||||
|
||||
if (impl->display_server.xdg_popup)
|
||||
{
|
||||
xdg_surface_ack_configure (impl->display_server.xdg_surface, serial);
|
||||
return;
|
||||
}
|
||||
else if (impl->display_server.zxdg_popup_v6)
|
||||
{
|
||||
zxdg_surface_v6_ack_configure (impl->display_server.zxdg_surface_v6,
|
||||
serial);
|
||||
return;
|
||||
}
|
||||
|
||||
new_state = impl->pending.state;
|
||||
impl->pending.state = 0;
|
||||
new_state = impl->pending.toplevel.state;
|
||||
impl->pending.toplevel.state = 0;
|
||||
|
||||
fixed_size =
|
||||
new_state & (GDK_SURFACE_STATE_MAXIMIZED |
|
||||
GDK_SURFACE_STATE_FULLSCREEN |
|
||||
GDK_SURFACE_STATE_TILED);
|
||||
|
||||
width = impl->pending.toplevel.width;
|
||||
height = impl->pending.toplevel.height;
|
||||
|
||||
saved_size = (width == 0 && height == 0);
|
||||
/* According to xdg_shell, an xdg_surface.configure with size 0x0
|
||||
* should be interpreted as that it is up to the client to set a
|
||||
@@ -1113,7 +1117,7 @@ gdk_wayland_surface_handle_configure (GdkSurface *surface,
|
||||
_gdk_wayland_surface_save_size (surface);
|
||||
}
|
||||
|
||||
gdk_wayland_surface_configure (surface, width, height, impl->scale);
|
||||
gdk_wayland_surface_resize (surface, width, height, impl->scale);
|
||||
}
|
||||
|
||||
GDK_DISPLAY_NOTE (gdk_surface_get_display (surface), EVENTS,
|
||||
@@ -1129,11 +1133,12 @@ gdk_wayland_surface_handle_configure (GdkSurface *surface,
|
||||
switch (display_wayland->shell_variant)
|
||||
{
|
||||
case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL:
|
||||
xdg_surface_ack_configure (impl->display_server.xdg_surface, serial);
|
||||
xdg_surface_ack_configure (impl->display_server.xdg_surface,
|
||||
impl->pending.serial);
|
||||
break;
|
||||
case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6:
|
||||
zxdg_surface_v6_ack_configure (impl->display_server.zxdg_surface_v6,
|
||||
serial);
|
||||
impl->pending.serial);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
@@ -1144,6 +1149,87 @@ gdk_wayland_surface_handle_configure (GdkSurface *surface,
|
||||
gdk_wayland_surface_update_dialogs (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_configure_popup (GdkSurface *surface)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
int x, y, width, height;
|
||||
GdkRectangle flipped_rect;
|
||||
GdkRectangle final_rect;
|
||||
gboolean flipped_x;
|
||||
gboolean flipped_y;
|
||||
|
||||
g_return_if_fail (impl->transient_for);
|
||||
|
||||
if (impl->display_server.xdg_popup)
|
||||
{
|
||||
xdg_surface_ack_configure (impl->display_server.xdg_surface,
|
||||
impl->pending.serial);
|
||||
}
|
||||
else if (impl->display_server.zxdg_popup_v6)
|
||||
{
|
||||
zxdg_surface_v6_ack_configure (impl->display_server.zxdg_surface_v6,
|
||||
impl->pending.serial);
|
||||
}
|
||||
|
||||
if (impl->position_method != POSITION_METHOD_MOVE_TO_RECT)
|
||||
return;
|
||||
|
||||
x = impl->pending.popup.x;
|
||||
y = impl->pending.popup.y;
|
||||
width = impl->pending.popup.width;
|
||||
height = impl->pending.popup.height;
|
||||
|
||||
gdk_wayland_surface_resize (surface, width, height, impl->scale);
|
||||
|
||||
calculate_moved_to_rect_result (surface,
|
||||
x, y,
|
||||
width, height,
|
||||
&flipped_rect,
|
||||
&final_rect,
|
||||
&flipped_x,
|
||||
&flipped_y);
|
||||
|
||||
impl->position_method = POSITION_METHOD_MOVE_TO_RECT;
|
||||
|
||||
g_signal_emit_by_name (surface,
|
||||
"moved-to-rect",
|
||||
&flipped_rect,
|
||||
&final_rect,
|
||||
flipped_x,
|
||||
flipped_y);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_configure (GdkSurface *surface)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
if (!impl->initial_configure_received)
|
||||
{
|
||||
gdk_surface_thaw_updates (surface);
|
||||
impl->initial_configure_received = TRUE;
|
||||
}
|
||||
|
||||
if (is_realized_popup (surface))
|
||||
gdk_wayland_surface_configure_popup (surface);
|
||||
else if (is_realized_toplevel (surface))
|
||||
gdk_wayland_surface_configure_toplevel (surface);
|
||||
else
|
||||
g_warn_if_reached ();
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_handle_configure (GdkSurface *surface,
|
||||
uint32_t serial)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
impl->pending.serial = serial;
|
||||
|
||||
gdk_wayland_surface_configure (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_handle_configure_toplevel (GdkSurface *surface,
|
||||
int32_t width,
|
||||
@@ -1152,9 +1238,9 @@ gdk_wayland_surface_handle_configure_toplevel (GdkSurface *surface,
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
impl->pending.state |= state;
|
||||
impl->pending.width = width;
|
||||
impl->pending.height = height;
|
||||
impl->pending.toplevel.state |= state;
|
||||
impl->pending.toplevel.width = width;
|
||||
impl->pending.toplevel.height = height;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1433,30 +1519,11 @@ gdk_wayland_surface_handle_configure_popup (GdkSurface *surface,
|
||||
int32_t height)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
GdkRectangle flipped_rect;
|
||||
GdkRectangle final_rect;
|
||||
gboolean flipped_x;
|
||||
gboolean flipped_y;
|
||||
|
||||
g_return_if_fail (impl->transient_for);
|
||||
|
||||
if (impl->position_method != POSITION_METHOD_MOVE_TO_RECT)
|
||||
return;
|
||||
|
||||
calculate_moved_to_rect_result (surface, x, y, width, height,
|
||||
&flipped_rect,
|
||||
&final_rect,
|
||||
&flipped_x,
|
||||
&flipped_y);
|
||||
|
||||
impl->position_method = POSITION_METHOD_MOVE_TO_RECT;
|
||||
|
||||
g_signal_emit_by_name (surface,
|
||||
"moved-to-rect",
|
||||
&flipped_rect,
|
||||
&final_rect,
|
||||
flipped_x,
|
||||
flipped_y);
|
||||
impl->pending.popup.x = x;
|
||||
impl->pending.popup.y = y;
|
||||
impl->pending.popup.width = width;
|
||||
impl->pending.popup.height = height;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1902,9 +1969,9 @@ calculate_moved_to_rect_result (GdkSurface *surface,
|
||||
surface_width = width + surface->shadow_left + surface->shadow_right;
|
||||
surface_height = height + surface->shadow_top + surface->shadow_bottom;
|
||||
|
||||
gdk_surface_move_resize (surface,
|
||||
surface_x, surface_y,
|
||||
surface_width, surface_height);
|
||||
gdk_wayland_surface_move_resize (surface,
|
||||
surface_x, surface_y,
|
||||
surface_width, surface_height);
|
||||
|
||||
calculate_popup_rect (surface,
|
||||
impl->pending_move_to_rect.rect_anchor,
|
||||
@@ -2647,7 +2714,6 @@ gdk_wayland_surface_restack_toplevel (GdkSurface *surface,
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_move_resize (GdkSurface *surface,
|
||||
gboolean with_move,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
@@ -2655,22 +2721,21 @@ gdk_wayland_surface_move_resize (GdkSurface *surface,
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
if (with_move)
|
||||
{
|
||||
/* Each toplevel has in its own "root" coordinate system */
|
||||
if (GDK_SURFACE_TYPE (surface) != GDK_SURFACE_TOPLEVEL)
|
||||
{
|
||||
surface->x = x;
|
||||
surface->y = y;
|
||||
impl->position_method = POSITION_METHOD_MOVE_RESIZE;
|
||||
}
|
||||
}
|
||||
surface->x = x;
|
||||
surface->y = y;
|
||||
gdk_wayland_surface_maybe_resize (surface, width, height, impl->scale);
|
||||
}
|
||||
|
||||
/* If this function is called with width and height = -1 then that means
|
||||
* just move the surface - don't update its size
|
||||
*/
|
||||
if (width > 0 && height > 0)
|
||||
gdk_wayland_surface_maybe_configure (surface, width, height, impl->scale);
|
||||
static void
|
||||
gdk_wayland_surface_toplevel_resize (GdkSurface *surface,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
gdk_wayland_surface_maybe_resize (surface,
|
||||
width, height,
|
||||
impl->scale);
|
||||
}
|
||||
|
||||
/* Avoid zero width/height as this is a protocol error */
|
||||
@@ -2924,7 +2989,7 @@ gtk_surface_configure (void *data,
|
||||
}
|
||||
}
|
||||
|
||||
impl->pending.state |= new_state;
|
||||
impl->pending.toplevel.state |= new_state;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2961,7 +3026,7 @@ gtk_surface_configure_edges (void *data,
|
||||
}
|
||||
}
|
||||
|
||||
impl->pending.state |= new_state;
|
||||
impl->pending.toplevel.state |= new_state;
|
||||
}
|
||||
|
||||
static const struct gtk_surface1_listener gtk_surface_listener = {
|
||||
@@ -3663,7 +3728,9 @@ gdk_wayland_surface_set_shadow_width (GdkSurface *surface,
|
||||
(impl->margin_left + impl->margin_right) + (left + right);
|
||||
new_height = surface->height -
|
||||
(impl->margin_top + impl->margin_bottom) + (top + bottom);
|
||||
gdk_wayland_surface_maybe_configure (surface, new_width, new_height, impl->scale);
|
||||
gdk_wayland_surface_maybe_resize (surface,
|
||||
new_width, new_height,
|
||||
impl->scale);
|
||||
|
||||
impl->margin_left = left;
|
||||
impl->margin_right = right;
|
||||
@@ -3746,7 +3813,7 @@ gdk_wayland_surface_class_init (GdkWaylandSurfaceClass *klass)
|
||||
impl_class->raise = gdk_wayland_surface_raise;
|
||||
impl_class->lower = gdk_wayland_surface_lower;
|
||||
impl_class->restack_toplevel = gdk_wayland_surface_restack_toplevel;
|
||||
impl_class->move_resize = gdk_wayland_surface_move_resize;
|
||||
impl_class->toplevel_resize = gdk_wayland_surface_toplevel_resize;
|
||||
impl_class->move_to_rect = gdk_wayland_surface_move_to_rect;
|
||||
impl_class->get_geometry = gdk_wayland_surface_get_geometry;
|
||||
impl_class->get_root_coords = gdk_wayland_surface_get_root_coords;
|
||||
|
||||
@@ -736,9 +736,9 @@ move_drag_surface (GdkDrag *drag,
|
||||
g_assert (_win32_main_thread == NULL ||
|
||||
_win32_main_thread == g_thread_self ());
|
||||
|
||||
gdk_surface_move (drag_win32->drag_surface,
|
||||
x_root - drag_win32->hot_x,
|
||||
y_root - drag_win32->hot_y);
|
||||
gdk_win32_surface_move (drag_win32->drag_surface,
|
||||
x_root - drag_win32->hot_x,
|
||||
y_root - drag_win32->hot_y);
|
||||
gdk_surface_raise (drag_win32->drag_surface);
|
||||
}
|
||||
|
||||
@@ -2090,6 +2090,7 @@ gdk_drag_anim_timeout (gpointer data)
|
||||
gint64 current_time;
|
||||
double f;
|
||||
double t;
|
||||
gint x, y;
|
||||
|
||||
if (!frame_clock)
|
||||
return G_SOURCE_REMOVE;
|
||||
@@ -2104,9 +2105,13 @@ gdk_drag_anim_timeout (gpointer data)
|
||||
t = ease_out_cubic (f);
|
||||
|
||||
gdk_surface_show (drag->drag_surface);
|
||||
gdk_surface_move (drag->drag_surface,
|
||||
drag->util_data.last_x + (drag->start_x - drag->util_data.last_x) * t - drag->hot_x,
|
||||
drag->util_data.last_y + (drag->start_y - drag->util_data.last_y) * t - drag->hot_y);
|
||||
x = (drag->util_data.last_x +
|
||||
(drag->start_x - drag->util_data.last_x) * t -
|
||||
drag->hot_x);
|
||||
y = (drag->util_data.last_y +
|
||||
(drag->start_y - drag->util_data.last_y) * t -
|
||||
drag->hot_y);
|
||||
gdk_win32_surface_move (drag->drag_surface, x, y);
|
||||
gdk_surface_set_opacity (drag->drag_surface, 1.0 - f);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
|
||||
@@ -1588,7 +1588,9 @@ handle_dpi_changed (GdkSurface *window,
|
||||
_gdk_win32_adjust_client_rect (window, rect);
|
||||
|
||||
if (impl->drag_move_resize_context.op != GDK_WIN32_DRAGOP_NONE)
|
||||
gdk_surface_move_resize (window, window->x, window->y, window->width, window->height);
|
||||
gdk_win32_surface_move_resize (window,
|
||||
window->x, window->y,
|
||||
window->width, window->height);
|
||||
else
|
||||
gdk_surface_resize (window, window->width, window->height);
|
||||
}
|
||||
|
||||
+102
-23
@@ -1098,8 +1098,8 @@ gdk_win32_surface_withdraw (GdkSurface *window)
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_surface_move (GdkSurface *window,
|
||||
gint x, gint y)
|
||||
gdk_win32_surface_do_move (GdkSurface *window,
|
||||
gint x, gint y)
|
||||
{
|
||||
RECT outer_rect;
|
||||
GdkWin32Surface *impl;
|
||||
@@ -1174,11 +1174,11 @@ gdk_win32_surface_resize (GdkSurface *window,
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_surface_move_resize_internal (GdkSurface *window,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
gdk_win32_surface_do_move_resize (GdkSurface *window,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
RECT outer_rect;
|
||||
GdkWin32Surface *impl;
|
||||
@@ -1224,12 +1224,12 @@ gdk_win32_surface_move_resize_internal (GdkSurface *window,
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_surface_move_resize (GdkSurface *window,
|
||||
gboolean with_move,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
gdk_win32_surface_move_resize_internal (GdkSurface *window,
|
||||
gboolean with_move,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
GdkWin32Surface *surface = GDK_WIN32_SURFACE (window);
|
||||
|
||||
@@ -1242,13 +1242,13 @@ gdk_win32_surface_move_resize (GdkSurface *window,
|
||||
|
||||
if (with_move && (width < 0 && height < 0))
|
||||
{
|
||||
gdk_win32_surface_move (window, x, y);
|
||||
gdk_win32_surface_do_move (window, x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (with_move)
|
||||
{
|
||||
gdk_win32_surface_move_resize_internal (window, x, y, width, height);
|
||||
gdk_win32_surface_do_move_resize (window, x, y, width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1262,6 +1262,80 @@ gdk_win32_surface_move_resize (GdkSurface *window,
|
||||
_gdk_win32_emit_configure_event (window);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_win32_surface_move_resize (GdkSurface *window,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
gdk_win32_surface_move_resize_internal (window, TRUE, x, y, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_surface_toplevel_resize (GdkSurface *surface,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
gdk_win32_surface_move_resize_internal (surface, FALSE, 0, 0, width, height);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_win32_surface_move (GdkSurface *surface,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
gdk_win32_surface_move_resize_internal (surface, TRUE, x, y, -1, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_surface_moved_to_rect (GdkSurface *surface,
|
||||
GdkRectangle final_rect)
|
||||
{
|
||||
GdkSurface *toplevel;
|
||||
int x, y;
|
||||
|
||||
if (surface->surface_type == GDK_SURFACE_POPUP)
|
||||
toplevel = surface->parent;
|
||||
else
|
||||
toplevel = surface->transient_for;
|
||||
|
||||
gdk_surface_get_origin (toplevel, &x, &y);
|
||||
x += final_rect.x;
|
||||
y += final_rect.y;
|
||||
|
||||
if (final_rect.width != surface->width ||
|
||||
final_rect.height != surface->height)
|
||||
{
|
||||
gdk_win32_surface_move_resize (surface,
|
||||
x, y,
|
||||
final_rect.width, final_rect.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
gdk_win32_surface_move (surface, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_surface_move_to_rect (GdkSurface *surface,
|
||||
const GdkRectangle *rect,
|
||||
GdkGravity rect_anchor,
|
||||
GdkGravity surface_anchor,
|
||||
GdkAnchorHints anchor_hints,
|
||||
gint rect_anchor_dx,
|
||||
gint rect_anchor_dy)
|
||||
{
|
||||
gdk_surface_move_to_rect_helper (surface,
|
||||
rect,
|
||||
rect_anchor,
|
||||
surface_anchor,
|
||||
anchor_hints,
|
||||
rect_anchor_dx,
|
||||
rect_anchor_dy,
|
||||
gdk_win32_surface_moved_to_rect);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_surface_raise (GdkSurface *window)
|
||||
{
|
||||
@@ -2518,8 +2592,8 @@ unsnap (GdkSurface *window,
|
||||
|
||||
GDK_NOTE (MISC, g_print ("Unsnapped window size %d x %d @ %d : %d\n", rect.width, rect.height, rect.x, rect.y));
|
||||
|
||||
gdk_surface_move_resize (window, rect.x, rect.y,
|
||||
rect.width, rect.height);
|
||||
gdk_win32_surface_move_resize (window, rect.x, rect.y,
|
||||
rect.width, rect.height);
|
||||
|
||||
g_clear_pointer (&impl->snap_stash, g_free);
|
||||
g_clear_pointer (&impl->snap_stash_int, g_free);
|
||||
@@ -2624,7 +2698,7 @@ snap_up (GdkSurface *window)
|
||||
width += impl->margins_x;
|
||||
height += impl->margins_y;
|
||||
|
||||
gdk_surface_move_resize (window, x, y, width, height);
|
||||
gdk_win32_surface_move_resize (window, x, y, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2650,7 +2724,9 @@ snap_left (GdkSurface *window,
|
||||
rect.width = rect.width + impl->margins_x;
|
||||
rect.height = rect.height + impl->margins_y;
|
||||
|
||||
gdk_surface_move_resize (window, rect.x, rect.y, rect.width, rect.height);
|
||||
gdk_win32_surface_move_resize (window,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2677,7 +2753,9 @@ snap_right (GdkSurface *window,
|
||||
rect.width = rect.width + impl->margins_x;
|
||||
rect.height = rect.height + impl->margins_y;
|
||||
|
||||
gdk_surface_move_resize (window, rect.x, rect.y, rect.width, rect.height);
|
||||
gdk_win32_surface_move_resize (window,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -3928,8 +4006,8 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
GDK_NOTE (MISC, g_print ("Unsnapped window to %d : %d\n",
|
||||
new_pos.x, new_pos.y));
|
||||
discard_snapinfo (window);
|
||||
gdk_surface_move_resize (window, new_pos.x, new_pos.y,
|
||||
new_pos.width, new_pos.height);
|
||||
gdk_win32_surface_move_resize (window, new_pos.x, new_pos.y,
|
||||
new_pos.width, new_pos.height);
|
||||
}
|
||||
|
||||
|
||||
@@ -5082,7 +5160,8 @@ gdk_win32_surface_class_init (GdkWin32SurfaceClass *klass)
|
||||
impl_class->raise = gdk_win32_surface_raise;
|
||||
impl_class->lower = gdk_win32_surface_lower;
|
||||
impl_class->restack_toplevel = gdk_win32_surface_restack_toplevel;
|
||||
impl_class->move_resize = gdk_win32_surface_move_resize;
|
||||
impl_class->toplevel_resize = gdk_win32_surface_toplevel_resize;
|
||||
impl_class->move_to_rect = gdk_win32_surface_move_to_rect;
|
||||
impl_class->get_geometry = gdk_win32_surface_get_geometry;
|
||||
impl_class->get_device_state = gdk_surface_win32_get_device_state;
|
||||
impl_class->get_root_coords = gdk_win32_surface_get_root_coords;
|
||||
|
||||
@@ -361,6 +361,15 @@ void _gdk_win32_update_layered_window_from_cache (GdkSurface *window,
|
||||
gboolean do_resize,
|
||||
gboolean do_paint);
|
||||
|
||||
void gdk_win32_surface_move (GdkSurface *surface,
|
||||
gint x,
|
||||
gint y);
|
||||
|
||||
void gdk_win32_surface_move_resize (GdkSurface *window,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
void
|
||||
gdk_win32_surface_get_queued_window_rect (GdkSurface *surface,
|
||||
|
||||
@@ -289,7 +289,7 @@ gdk_x11_app_launch_context_get_startup_notify_id (GAppLaunchContext *context,
|
||||
files_count = g_list_length (files);
|
||||
if (files_count == 0)
|
||||
{
|
||||
description = g_strdup_printf (_("Starting %s"), g_app_info_get_name (info));
|
||||
description = g_strdup_printf (_("Starting “%s”"), g_app_info_get_name (info));
|
||||
}
|
||||
else if (files_count == 1)
|
||||
{
|
||||
@@ -302,7 +302,7 @@ gdk_x11_app_launch_context_get_startup_notify_id (GAppLaunchContext *context,
|
||||
0, NULL, NULL);
|
||||
|
||||
display_name = get_display_name (files->data, fileinfo);
|
||||
description = g_strdup_printf (_("Opening %s"), display_name);
|
||||
description = g_strdup_printf (_("Opening “%s”"), display_name);
|
||||
g_free (display_name);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1459,9 +1459,9 @@ move_drag_surface (GdkDrag *drag,
|
||||
{
|
||||
GdkX11Drag *drag_x11 = GDK_X11_DRAG (drag);
|
||||
|
||||
gdk_surface_move (drag_x11->drag_surface,
|
||||
x_root - drag_x11->hot_x,
|
||||
y_root - drag_x11->hot_y);
|
||||
gdk_x11_surface_move (drag_x11->drag_surface,
|
||||
x_root - drag_x11->hot_x,
|
||||
y_root - drag_x11->hot_y);
|
||||
gdk_surface_raise (drag_x11->drag_surface);
|
||||
}
|
||||
|
||||
@@ -1841,9 +1841,9 @@ gdk_drag_anim_timeout (gpointer data)
|
||||
t = ease_out_cubic (f);
|
||||
|
||||
gdk_surface_show (drag->drag_surface);
|
||||
gdk_surface_move (drag->drag_surface,
|
||||
drag->last_x + (drag->start_x - drag->last_x) * t,
|
||||
drag->last_y + (drag->start_y - drag->last_y) * t);
|
||||
gdk_x11_surface_move (drag->drag_surface,
|
||||
drag->last_x + (drag->start_x - drag->last_x) * t,
|
||||
drag->last_y + (drag->start_y - drag->last_y) * t);
|
||||
gdk_surface_set_opacity (drag->drag_surface, 1.0 - f);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
|
||||
@@ -1392,6 +1392,71 @@ gdk_x11_surface_move_resize (GdkSurface *surface,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_x11_surface_toplevel_resize (GdkSurface *surface,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
x11_surface_resize (surface, width, height);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_x11_surface_move (GdkSurface *surface,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
gdk_x11_surface_move_resize (surface, TRUE, x, y, -1, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_x11_surface_moved_to_rect (GdkSurface *surface,
|
||||
GdkRectangle final_rect)
|
||||
{
|
||||
GdkSurface *toplevel;
|
||||
int x, y;
|
||||
|
||||
if (surface->surface_type == GDK_SURFACE_POPUP)
|
||||
toplevel = surface->parent;
|
||||
else
|
||||
toplevel = surface->transient_for;
|
||||
|
||||
gdk_surface_get_origin (toplevel, &x, &y);
|
||||
x += final_rect.x;
|
||||
y += final_rect.y;
|
||||
|
||||
if (final_rect.width != surface->width ||
|
||||
final_rect.height != surface->height)
|
||||
{
|
||||
gdk_x11_surface_move_resize (surface,
|
||||
TRUE,
|
||||
x, y,
|
||||
final_rect.width, final_rect.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
gdk_x11_surface_move (surface, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_x11_surface_move_to_rect (GdkSurface *surface,
|
||||
const GdkRectangle *rect,
|
||||
GdkGravity rect_anchor,
|
||||
GdkGravity surface_anchor,
|
||||
GdkAnchorHints anchor_hints,
|
||||
gint rect_anchor_dx,
|
||||
gint rect_anchor_dy)
|
||||
{
|
||||
gdk_surface_move_to_rect_helper (surface,
|
||||
rect,
|
||||
rect_anchor,
|
||||
surface_anchor,
|
||||
anchor_hints,
|
||||
rect_anchor_dx,
|
||||
rect_anchor_dy,
|
||||
gdk_x11_surface_moved_to_rect);
|
||||
}
|
||||
|
||||
static void gdk_x11_surface_restack_toplevel (GdkSurface *surface,
|
||||
GdkSurface *sibling,
|
||||
gboolean above);
|
||||
@@ -3245,7 +3310,7 @@ gdk_x11_surface_fullscreen_on_monitor (GdkSurface *surface,
|
||||
return;
|
||||
|
||||
gdk_monitor_get_geometry (monitor, &geom);
|
||||
gdk_surface_move (surface, geom.x, geom.y);
|
||||
gdk_x11_surface_move (surface, geom.x, geom.y);
|
||||
|
||||
gdk_surface_set_fullscreen_mode (surface, GDK_FULLSCREEN_ON_CURRENT_MONITOR);
|
||||
gdk_x11_surface_fullscreen (surface);
|
||||
@@ -3887,7 +3952,8 @@ update_pos (MoveResizeData *mv_resize,
|
||||
w, h, &w, &h);
|
||||
}
|
||||
|
||||
gdk_surface_move_resize (mv_resize->moveresize_surface, x, y, w, h);
|
||||
gdk_x11_surface_move_resize (mv_resize->moveresize_surface, TRUE,
|
||||
x, y, w, h);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3896,7 +3962,7 @@ update_pos (MoveResizeData *mv_resize,
|
||||
x = mv_resize->moveresize_orig_x + dx;
|
||||
y = mv_resize->moveresize_orig_y + dy;
|
||||
|
||||
gdk_surface_move (mv_resize->moveresize_surface, x, y);
|
||||
gdk_x11_surface_move (mv_resize->moveresize_surface, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4589,7 +4655,8 @@ gdk_x11_surface_class_init (GdkX11SurfaceClass *klass)
|
||||
impl_class->raise = gdk_x11_surface_raise;
|
||||
impl_class->lower = gdk_x11_surface_lower;
|
||||
impl_class->restack_toplevel = gdk_x11_surface_restack_toplevel;
|
||||
impl_class->move_resize = gdk_x11_surface_move_resize;
|
||||
impl_class->toplevel_resize = gdk_x11_surface_toplevel_resize;
|
||||
impl_class->move_to_rect = gdk_x11_surface_move_to_rect;
|
||||
impl_class->get_geometry = gdk_x11_surface_get_geometry;
|
||||
impl_class->get_root_coords = gdk_x11_surface_get_root_coords;
|
||||
impl_class->get_device_state = gdk_x11_surface_get_device_state;
|
||||
|
||||
@@ -183,6 +183,10 @@ void _gdk_x11_surface_set_surface_scale (GdkSurface *window,
|
||||
|
||||
void gdk_x11_surface_pre_damage (GdkSurface *surface);
|
||||
|
||||
void gdk_x11_surface_move (GdkSurface *surface,
|
||||
gint x,
|
||||
gint y);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_X11_SURFACE__ */
|
||||
|
||||
+70
-84
@@ -24,6 +24,7 @@
|
||||
*/
|
||||
|
||||
#define MAX_FRAME_AGE (5 * 60)
|
||||
#define MAX_GLYPH_SIZE 128 /* Will get its own texture if bigger */
|
||||
|
||||
static guint glyph_cache_hash (gconstpointer v);
|
||||
static gboolean glyph_cache_equal (gconstpointer v1,
|
||||
@@ -82,6 +83,8 @@ glyph_cache_equal (gconstpointer v1, gconstpointer v2)
|
||||
|
||||
return key1->font == key2->font &&
|
||||
key1->glyph == key2->glyph &&
|
||||
key1->xshift == key2->xshift &&
|
||||
key1->yshift == key2->yshift &&
|
||||
key1->scale == key2->scale;
|
||||
}
|
||||
|
||||
@@ -90,7 +93,11 @@ glyph_cache_hash (gconstpointer v)
|
||||
{
|
||||
const GlyphCacheKey *key = v;
|
||||
|
||||
return GPOINTER_TO_UINT (key->font) ^ key->glyph ^ key->scale;
|
||||
return GPOINTER_TO_UINT (key->font) ^
|
||||
key->glyph ^
|
||||
(key->xshift << 24) ^
|
||||
(key->yshift << 26) ^
|
||||
key->scale;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -116,8 +123,7 @@ render_glyph (GlyphCacheKey *key,
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
cairo_scaled_font_t *scaled_font;
|
||||
PangoGlyphString glyph_string;
|
||||
PangoGlyphInfo glyph_info;
|
||||
cairo_glyph_t cairo_glyph;
|
||||
int surface_width, surface_height;
|
||||
int stride;
|
||||
unsigned char *data;
|
||||
@@ -144,18 +150,14 @@ render_glyph (GlyphCacheKey *key,
|
||||
cairo_set_scaled_font (cr, scaled_font);
|
||||
cairo_set_source_rgba (cr, 1, 1, 1, 1);
|
||||
|
||||
glyph_info.glyph = key->glyph;
|
||||
glyph_info.geometry.width = value->draw_width * 1024;
|
||||
cairo_glyph.index = key->glyph;
|
||||
if (key->glyph & PANGO_GLYPH_UNKNOWN_FLAG)
|
||||
glyph_info.geometry.x_offset = 0;
|
||||
cairo_glyph.x = 0.25 * key->xshift;
|
||||
else
|
||||
glyph_info.geometry.x_offset = - value->draw_x * 1024;
|
||||
glyph_info.geometry.y_offset = - value->draw_y * 1024;
|
||||
cairo_glyph.x = 0.25 * key->xshift - value->draw_x;
|
||||
cairo_glyph.y = 0.25 * key->yshift - value->draw_y;
|
||||
|
||||
glyph_string.num_glyphs = 1;
|
||||
glyph_string.glyphs = &glyph_info;
|
||||
|
||||
pango_cairo_show_glyph_string (cr, key->font, &glyph_string);
|
||||
cairo_show_glyphs (cr, &cairo_glyph, 1);
|
||||
cairo_destroy (cr);
|
||||
|
||||
cairo_surface_flush (surface);
|
||||
@@ -206,85 +208,69 @@ upload_glyph (GlyphCacheKey *key,
|
||||
static void
|
||||
add_to_cache (GskGLGlyphCache *self,
|
||||
GlyphCacheKey *key,
|
||||
GskGLDriver *driver,
|
||||
GskGLCachedGlyph *value)
|
||||
{
|
||||
const int width = value->draw_width * key->scale / 1024;
|
||||
const int height = value->draw_height * key->scale / 1024;
|
||||
GskGLTextureAtlas *atlas = NULL;
|
||||
int packed_x = 0;
|
||||
int packed_y = 0;
|
||||
|
||||
gsk_gl_texture_atlases_pack (self->atlases, width + 2, height + 2, &atlas, &packed_x, &packed_y);
|
||||
if (width < MAX_GLYPH_SIZE && height < MAX_GLYPH_SIZE)
|
||||
{
|
||||
GskGLTextureAtlas *atlas = NULL;
|
||||
int packed_x = 0;
|
||||
int packed_y = 0;
|
||||
|
||||
value->tx = (float)(packed_x + 1) / atlas->width;
|
||||
value->ty = (float)(packed_y + 1) / atlas->height;
|
||||
value->tw = (float)width / atlas->width;
|
||||
value->th = (float)height / atlas->height;
|
||||
value->used = TRUE;
|
||||
gsk_gl_texture_atlases_pack (self->atlases, width + 2, height + 2, &atlas, &packed_x, &packed_y);
|
||||
|
||||
value->tx = (float)(packed_x + 1) / atlas->width;
|
||||
value->ty = (float)(packed_y + 1) / atlas->height;
|
||||
value->tw = (float)width / atlas->width;
|
||||
value->th = (float)height / atlas->height;
|
||||
value->used = TRUE;
|
||||
|
||||
value->atlas = atlas;
|
||||
value->texture_id = atlas->texture_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
value->atlas = NULL;
|
||||
value->texture_id = gsk_gl_driver_create_texture (driver, width, height);
|
||||
|
||||
gsk_gl_driver_bind_source_texture (driver, value->texture_id);
|
||||
gsk_gl_driver_init_texture_empty (driver, value->texture_id, GL_NEAREST, GL_NEAREST);
|
||||
|
||||
value->tx = 0.0f;
|
||||
value->ty = 0.0f;
|
||||
value->tw = 1.0f;
|
||||
value->th = 1.0f;
|
||||
}
|
||||
|
||||
value->atlas = atlas;
|
||||
value->texture_id = atlas->texture_id;
|
||||
|
||||
upload_glyph (key, value);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gl_glyph_cache_get_texture (GskGLDriver *driver,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph,
|
||||
float scale,
|
||||
GskGLCachedGlyph *value)
|
||||
{
|
||||
PangoRectangle ink_rect;
|
||||
GlyphCacheKey key;
|
||||
int width, height;
|
||||
guint texture_id;
|
||||
|
||||
pango_font_get_glyph_extents (font, glyph, &ink_rect, NULL);
|
||||
pango_extents_to_pixels (&ink_rect, NULL);
|
||||
|
||||
key.font = font;
|
||||
key.glyph = glyph;
|
||||
key.scale = (guint)(scale * 1024);
|
||||
|
||||
value->atlas = NULL;
|
||||
value->timestamp = 0;
|
||||
|
||||
value->draw_x = ink_rect.x;
|
||||
value->draw_y = ink_rect.y;
|
||||
value->draw_width = ink_rect.width;
|
||||
value->draw_height = ink_rect.height;
|
||||
|
||||
value->tx = 0.0f;
|
||||
value->ty = 0.0f;
|
||||
value->tw = 1.0f;
|
||||
value->th = 1.0f;
|
||||
|
||||
width = value->draw_width * key.scale / 1024;
|
||||
height = value->draw_height * key.scale / 1024;
|
||||
|
||||
texture_id = gsk_gl_driver_create_texture (driver, width, height);
|
||||
gsk_gl_driver_bind_source_texture (driver, texture_id);
|
||||
gsk_gl_driver_init_texture_empty (driver, texture_id, GL_NEAREST, GL_NEAREST);
|
||||
|
||||
value->texture_id = texture_id;
|
||||
|
||||
upload_glyph (&key, value);
|
||||
}
|
||||
#define PHASE(x) ((x % PANGO_SCALE) * 4 / PANGO_SCALE)
|
||||
|
||||
gboolean
|
||||
gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph,
|
||||
int x,
|
||||
int y,
|
||||
float scale,
|
||||
GskGLDriver *driver,
|
||||
GskGLCachedGlyph *cached_glyph_out)
|
||||
{
|
||||
GskGLCachedGlyph *value;
|
||||
guint xshift = PHASE (x);
|
||||
guint yshift = PHASE (y);
|
||||
|
||||
value = g_hash_table_lookup (cache->hash_table,
|
||||
&(GlyphCacheKey) {
|
||||
.font = font,
|
||||
.glyph = glyph,
|
||||
.xshift = xshift,
|
||||
.yshift = yshift,
|
||||
.scale = (guint)(scale * 1024)
|
||||
});
|
||||
|
||||
@@ -310,10 +296,16 @@ gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache,
|
||||
|
||||
if (value == NULL)
|
||||
{
|
||||
GlyphCacheKey *key;
|
||||
PangoRectangle ink_rect;
|
||||
const guint key_scale = (guint)(scale * 1024);
|
||||
|
||||
pango_font_get_glyph_extents (font, glyph, &ink_rect, NULL);
|
||||
pango_extents_to_pixels (&ink_rect, NULL);
|
||||
if (xshift != 0)
|
||||
ink_rect.width += 1;
|
||||
if (yshift != 0)
|
||||
ink_rect.height += 1;
|
||||
|
||||
value = g_new0 (GskGLCachedGlyph, 1);
|
||||
|
||||
@@ -324,27 +316,21 @@ gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache,
|
||||
value->timestamp = cache->timestamp;
|
||||
value->atlas = NULL; /* For now */
|
||||
|
||||
if (ink_rect.width < 128 && ink_rect.height < 128)
|
||||
{
|
||||
GlyphCacheKey *key;
|
||||
key = g_new0 (GlyphCacheKey, 1);
|
||||
|
||||
key = g_new0 (GlyphCacheKey, 1);
|
||||
key->font = g_object_ref (font);
|
||||
key->glyph = glyph;
|
||||
key->xshift = xshift;
|
||||
key->yshift = yshift;
|
||||
key->scale = key_scale;
|
||||
|
||||
key->font = g_object_ref (font);
|
||||
key->glyph = glyph;
|
||||
key->scale = (guint)(scale * 1024);
|
||||
if (key->scale > 0 &&
|
||||
ink_rect.width * key->scale > 0 &&
|
||||
ink_rect.height * key->scale > 0)
|
||||
add_to_cache (cache, key, driver, value);
|
||||
|
||||
if (ink_rect.width > 0 && ink_rect.height > 0 && key->scale > 0)
|
||||
add_to_cache (cache, key, value);
|
||||
|
||||
*cached_glyph_out = *value;
|
||||
g_hash_table_insert (cache->hash_table, key, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
*cached_glyph_out = *value;
|
||||
glyph_cache_value_free (value);
|
||||
}
|
||||
*cached_glyph_out = *value;
|
||||
g_hash_table_insert (cache->hash_table, key, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -22,6 +22,8 @@ typedef struct
|
||||
{
|
||||
PangoFont *font;
|
||||
PangoGlyph glyph;
|
||||
guint xshift;
|
||||
guint yshift;
|
||||
guint scale; /* times 1024 */
|
||||
} GlyphCacheKey;
|
||||
|
||||
@@ -55,12 +57,10 @@ void gsk_gl_glyph_cache_begin_frame (GskGLGlyphCache
|
||||
gboolean gsk_gl_glyph_cache_lookup (GskGLGlyphCache *self,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph,
|
||||
int x,
|
||||
int y,
|
||||
float scale,
|
||||
GskGLCachedGlyph *cached_glyph_out);
|
||||
void gsk_gl_glyph_cache_get_texture (GskGLDriver *driver,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph,
|
||||
float scale,
|
||||
GskGLCachedGlyph *glyph_out);
|
||||
GskGLDriver *driver,
|
||||
GskGLCachedGlyph *cached_glyph_out);
|
||||
|
||||
#endif
|
||||
|
||||
+19
-25
@@ -595,26 +595,21 @@ render_text_node (GskGLRenderer *self,
|
||||
gsk_gl_glyph_cache_lookup (self->glyph_cache,
|
||||
(PangoFont *)font,
|
||||
gi->glyph,
|
||||
x * PANGO_SCALE + x_position + gi->geometry.x_offset,
|
||||
+ y * PANGO_SCALE + gi->geometry.y_offset,
|
||||
text_scale,
|
||||
self->gl_driver,
|
||||
&glyph);
|
||||
|
||||
/* e.g. whitespace */
|
||||
if (glyph.draw_width <= 0 || glyph.draw_height <= 0)
|
||||
goto next;
|
||||
|
||||
/* big glyphs are not cached */
|
||||
if (!glyph.texture_id)
|
||||
{
|
||||
gsk_gl_glyph_cache_get_texture (self->gl_driver,
|
||||
(PangoFont *)font,
|
||||
gi->glyph,
|
||||
text_scale,
|
||||
&glyph);
|
||||
g_assert (glyph.texture_id != 0);
|
||||
}
|
||||
if (glyph.texture_id == 0)
|
||||
goto next;
|
||||
|
||||
cx = (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
|
||||
cy = (double)(gi->geometry.y_offset) / PANGO_SCALE;
|
||||
cx = (x_position + gi->geometry.x_offset) / PANGO_SCALE;
|
||||
cy = gi->geometry.y_offset / PANGO_SCALE;
|
||||
|
||||
ops_set_texture (builder, glyph.texture_id);
|
||||
|
||||
@@ -1428,7 +1423,7 @@ render_blur_node (GskGLRenderer *self,
|
||||
ops_set_program (builder, &self->blur_program);
|
||||
op.op = OP_CHANGE_BLUR;
|
||||
graphene_size_init_from_size (&op.blur.size, &node->bounds.size);
|
||||
op.blur.radius = gsk_blur_node_get_radius (node);
|
||||
op.blur.radius = blur_radius;
|
||||
ops_add (builder, &op);
|
||||
|
||||
ops_set_texture (builder, region.texture_id);
|
||||
@@ -1439,7 +1434,7 @@ render_blur_node (GskGLRenderer *self,
|
||||
{ { min_x, min_y }, { 0, 1 }, },
|
||||
{ { min_x, max_y }, { 0, 0 }, },
|
||||
{ { max_x, min_y }, { 1, 1 }, },
|
||||
|
||||
|
||||
{ { max_x, max_y }, { 1, 0 }, },
|
||||
{ { min_x, max_y }, { 0, 0 }, },
|
||||
{ { max_x, min_y }, { 1, 1 }, },
|
||||
@@ -1890,10 +1885,10 @@ render_shadow_node (GskGLRenderer *self,
|
||||
RenderOpBuilder *builder,
|
||||
const GskQuadVertex *vertex_data)
|
||||
{
|
||||
float min_x = node->bounds.origin.x;
|
||||
float min_y = node->bounds.origin.y;
|
||||
float max_x = min_x + node->bounds.size.width;
|
||||
float max_y = min_y + node->bounds.size.height;
|
||||
float min_x;
|
||||
float min_y;
|
||||
float max_x;
|
||||
float max_y;
|
||||
GskRenderNode *original_child = gsk_shadow_node_get_child (node);
|
||||
GskRenderNode *shadow_child = original_child;
|
||||
gsize n_shadows = gsk_shadow_node_get_n_shadows (node);
|
||||
@@ -1919,6 +1914,11 @@ render_shadow_node (GskGLRenderer *self,
|
||||
shadow_child = gsk_color_matrix_node_get_child (shadow_child);
|
||||
}
|
||||
|
||||
min_x = builder->dx + shadow_child->bounds.origin.x;
|
||||
min_y = builder->dy + shadow_child->bounds.origin.y;
|
||||
max_x = min_x + shadow_child->bounds.size.width;
|
||||
max_y = min_y + shadow_child->bounds.size.height;
|
||||
|
||||
for (i = 0; i < n_shadows; i ++)
|
||||
{
|
||||
const GskShadow *shadow = gsk_shadow_node_peek_shadow (node, i);
|
||||
@@ -1940,11 +1940,6 @@ render_shadow_node (GskGLRenderer *self,
|
||||
if (gdk_rgba_is_clear (&shadow->color))
|
||||
continue;
|
||||
|
||||
min_x = builder->dx + shadow_child->bounds.origin.x;
|
||||
min_y = builder->dy + shadow_child->bounds.origin.y;
|
||||
max_x = min_x + shadow_child->bounds.size.width;
|
||||
max_y = min_y + shadow_child->bounds.size.height;
|
||||
|
||||
/* Draw the child offscreen, without the offset. */
|
||||
add_offscreen_ops (self, builder,
|
||||
&shadow_child->bounds,
|
||||
@@ -3196,7 +3191,7 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
|
||||
int scale_factor)
|
||||
{
|
||||
GskGLRenderer *self = GSK_GL_RENDERER (renderer);
|
||||
graphene_matrix_t modelview, projection;
|
||||
graphene_matrix_t projection;
|
||||
gsize buffer_size;
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
GskProfiler *profiler;
|
||||
@@ -3216,7 +3211,6 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
|
||||
g_assert (gsk_gl_driver_in_frame (self->gl_driver));
|
||||
|
||||
/* Set up the modelview and projection matrices to fit our viewport */
|
||||
graphene_matrix_init_scale (&modelview, scale_factor, scale_factor, 1.0);
|
||||
graphene_matrix_init_ortho (&projection,
|
||||
viewport->origin.x,
|
||||
viewport->origin.x + viewport->size.width,
|
||||
|
||||
+53
-32
@@ -8,6 +8,15 @@ rect_equal (const graphene_rect_t *a,
|
||||
return memcmp (a, b, sizeof (graphene_rect_t)) == 0;
|
||||
}
|
||||
|
||||
static inline ProgramState *
|
||||
get_current_program_state (RenderOpBuilder *builder)
|
||||
{
|
||||
if (!builder->current_program)
|
||||
return NULL;
|
||||
|
||||
return &builder->program_state[builder->current_program->index];
|
||||
}
|
||||
|
||||
void
|
||||
ops_finish (RenderOpBuilder *builder)
|
||||
{
|
||||
@@ -27,7 +36,6 @@ ops_finish (RenderOpBuilder *builder)
|
||||
builder->current_render_target = 0;
|
||||
builder->current_texture = 0;
|
||||
builder->current_program = NULL;
|
||||
builder->current_program_state = NULL;
|
||||
graphene_matrix_init_identity (&builder->current_projection);
|
||||
builder->current_viewport = GRAPHENE_RECT_INIT (0, 0, 0, 0);
|
||||
}
|
||||
@@ -265,8 +273,6 @@ ops_set_program (RenderOpBuilder *builder,
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
program_state->opacity = builder->current_opacity;
|
||||
}
|
||||
|
||||
builder->current_program_state = &builder->program_state[program->index];
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -274,9 +280,10 @@ ops_set_clip (RenderOpBuilder *builder,
|
||||
const GskRoundedRect *clip)
|
||||
{
|
||||
RenderOp *last_op;
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
|
||||
if (builder->current_program_state &&
|
||||
memcmp (&builder->current_program_state->clip, clip,sizeof (GskRoundedRect)) == 0)
|
||||
if (current_program_state &&
|
||||
memcmp (¤t_program_state->clip, clip,sizeof (GskRoundedRect)) == 0)
|
||||
return;
|
||||
|
||||
if (builder->render_ops->len > 0)
|
||||
@@ -298,7 +305,7 @@ ops_set_clip (RenderOpBuilder *builder,
|
||||
}
|
||||
|
||||
if (builder->current_program != NULL)
|
||||
builder->current_program_state->clip = *clip;
|
||||
current_program_state->clip = *clip;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -348,6 +355,7 @@ static void
|
||||
ops_set_modelview_internal (RenderOpBuilder *builder,
|
||||
GskTransform *transform)
|
||||
{
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
RenderOp op;
|
||||
graphene_matrix_t matrix;
|
||||
|
||||
@@ -382,10 +390,18 @@ ops_set_modelview_internal (RenderOpBuilder *builder,
|
||||
}
|
||||
|
||||
if (builder->current_program != NULL)
|
||||
builder->current_program_state->modelview = transform;
|
||||
{
|
||||
gsk_transform_unref (current_program_state->modelview);
|
||||
current_program_state->modelview = gsk_transform_ref (transform);
|
||||
}
|
||||
}
|
||||
|
||||
/* This sets the modelview to the given one without looking at the
|
||||
/**
|
||||
* ops_set_modelview:
|
||||
* @builder
|
||||
* @transform: (transfer full): The new modelview transform
|
||||
*
|
||||
* This sets the modelview to the given one without looking at the
|
||||
* one that's currently set */
|
||||
void
|
||||
ops_set_modelview (RenderOpBuilder *builder,
|
||||
@@ -401,11 +417,11 @@ ops_set_modelview (RenderOpBuilder *builder,
|
||||
g_array_set_size (builder->mv_stack, builder->mv_stack->len + 1);
|
||||
entry = &g_array_index (builder->mv_stack, MatrixStackEntry, builder->mv_stack->len - 1);
|
||||
|
||||
entry->transform = gsk_transform_ref (transform);
|
||||
entry->transform = transform;
|
||||
|
||||
entry->metadata.dx_before = builder->dx;
|
||||
entry->metadata.dy_before = builder->dy;
|
||||
extract_matrix_metadata (transform, &entry->metadata);
|
||||
extract_matrix_metadata (entry->transform, &entry->metadata);
|
||||
|
||||
builder->dx = 0;
|
||||
builder->dy = 0;
|
||||
@@ -419,7 +435,6 @@ void
|
||||
ops_push_modelview (RenderOpBuilder *builder,
|
||||
GskTransform *transform)
|
||||
{
|
||||
float scale = ops_get_scale (builder);
|
||||
MatrixStackEntry *entry;
|
||||
|
||||
if (G_UNLIKELY (builder->mv_stack == NULL))
|
||||
@@ -439,10 +454,9 @@ ops_push_modelview (RenderOpBuilder *builder,
|
||||
/* Multiply given matrix with current modelview */
|
||||
|
||||
t = gsk_transform_translate (gsk_transform_ref (cur->transform),
|
||||
&(graphene_point_t) { builder->dx * scale, builder->dy * scale});
|
||||
&(graphene_point_t) { builder->dx, builder->dy});
|
||||
t = gsk_transform_transform (t, transform);
|
||||
entry->transform = t;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -451,7 +465,6 @@ ops_push_modelview (RenderOpBuilder *builder,
|
||||
|
||||
entry->metadata.dx_before = builder->dx;
|
||||
entry->metadata.dy_before = builder->dy;
|
||||
|
||||
extract_matrix_metadata (entry->transform, &entry->metadata);
|
||||
|
||||
builder->dx = 0;
|
||||
@@ -491,6 +504,7 @@ graphene_matrix_t
|
||||
ops_set_projection (RenderOpBuilder *builder,
|
||||
const graphene_matrix_t *projection)
|
||||
{
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
RenderOp op;
|
||||
graphene_matrix_t prev_mv;
|
||||
|
||||
@@ -516,7 +530,7 @@ ops_set_projection (RenderOpBuilder *builder,
|
||||
}
|
||||
|
||||
if (builder->current_program != NULL)
|
||||
builder->current_program_state->projection = *projection;
|
||||
current_program_state->projection = *projection;
|
||||
|
||||
prev_mv = builder->current_projection;
|
||||
builder->current_projection = *projection;
|
||||
@@ -528,19 +542,20 @@ graphene_rect_t
|
||||
ops_set_viewport (RenderOpBuilder *builder,
|
||||
const graphene_rect_t *viewport)
|
||||
{
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
RenderOp op;
|
||||
graphene_rect_t prev_viewport;
|
||||
|
||||
if (builder->current_program_state != NULL &&
|
||||
rect_equal (&builder->current_program_state->viewport, viewport))
|
||||
return builder->current_program_state->viewport;
|
||||
if (current_program_state != NULL &&
|
||||
rect_equal (¤t_program_state->viewport, viewport))
|
||||
return current_program_state->viewport;
|
||||
|
||||
op.op = OP_CHANGE_VIEWPORT;
|
||||
op.viewport = *viewport;
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
|
||||
if (builder->current_program != NULL)
|
||||
builder->current_program_state->viewport = *viewport;
|
||||
current_program_state->viewport = *viewport;
|
||||
|
||||
prev_viewport = builder->current_viewport;
|
||||
builder->current_viewport = *viewport;
|
||||
@@ -605,6 +620,7 @@ float
|
||||
ops_set_opacity (RenderOpBuilder *builder,
|
||||
float opacity)
|
||||
{
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
RenderOp op;
|
||||
float prev_opacity;
|
||||
RenderOp *last_op;
|
||||
@@ -638,7 +654,7 @@ ops_set_opacity (RenderOpBuilder *builder,
|
||||
builder->current_opacity = opacity;
|
||||
|
||||
if (builder->current_program != NULL)
|
||||
builder->current_program_state->opacity = opacity;
|
||||
current_program_state->opacity = opacity;
|
||||
|
||||
return prev_opacity;
|
||||
}
|
||||
@@ -647,12 +663,13 @@ void
|
||||
ops_set_color (RenderOpBuilder *builder,
|
||||
const GdkRGBA *color)
|
||||
{
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
RenderOp op;
|
||||
|
||||
if (gdk_rgba_equal (color, &builder->current_program_state->color))
|
||||
if (gdk_rgba_equal (color, ¤t_program_state->color))
|
||||
return;
|
||||
|
||||
builder->current_program_state->color = *color;
|
||||
current_program_state->color = *color;
|
||||
|
||||
op.op = OP_CHANGE_COLOR;
|
||||
op.color = *color;
|
||||
@@ -664,18 +681,19 @@ ops_set_color_matrix (RenderOpBuilder *builder,
|
||||
const graphene_matrix_t *matrix,
|
||||
const graphene_vec4_t *offset)
|
||||
{
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
RenderOp op;
|
||||
|
||||
if (memcmp (matrix,
|
||||
&builder->current_program_state->color_matrix.matrix,
|
||||
¤t_program_state->color_matrix.matrix,
|
||||
sizeof (graphene_matrix_t)) == 0 &&
|
||||
memcmp (offset,
|
||||
&builder->current_program_state->color_matrix.offset,
|
||||
¤t_program_state->color_matrix.offset,
|
||||
sizeof (graphene_vec4_t)) == 0)
|
||||
return;
|
||||
|
||||
builder->current_program_state->color_matrix.matrix = *matrix;
|
||||
builder->current_program_state->color_matrix.offset = *offset;
|
||||
current_program_state->color_matrix.matrix = *matrix;
|
||||
current_program_state->color_matrix.offset = *offset;
|
||||
|
||||
op.op = OP_CHANGE_COLOR_MATRIX;
|
||||
op.color_matrix.matrix = *matrix;
|
||||
@@ -687,13 +705,14 @@ void
|
||||
ops_set_border (RenderOpBuilder *builder,
|
||||
const GskRoundedRect *outline)
|
||||
{
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
RenderOp op;
|
||||
|
||||
if (memcmp (&builder->current_program_state->border.outline,
|
||||
if (memcmp (¤t_program_state->border.outline,
|
||||
outline, sizeof (GskRoundedRect)) == 0)
|
||||
return;
|
||||
|
||||
builder->current_program_state->border.outline = *outline;
|
||||
current_program_state->border.outline = *outline;
|
||||
|
||||
op.op = OP_CHANGE_BORDER;
|
||||
op.border.outline = *outline;
|
||||
@@ -704,13 +723,14 @@ void
|
||||
ops_set_border_width (RenderOpBuilder *builder,
|
||||
const float *widths)
|
||||
{
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
RenderOp op;
|
||||
|
||||
if (memcmp (builder->current_program_state->border.widths,
|
||||
if (memcmp (current_program_state->border.widths,
|
||||
widths, sizeof (float) * 4) == 0)
|
||||
return;
|
||||
|
||||
memcpy (&builder->current_program_state->border.widths,
|
||||
memcpy (¤t_program_state->border.widths,
|
||||
widths, sizeof (float) * 4);
|
||||
|
||||
op.op = OP_CHANGE_BORDER_WIDTH;
|
||||
@@ -726,15 +746,16 @@ void
|
||||
ops_set_border_color (RenderOpBuilder *builder,
|
||||
const GdkRGBA *color)
|
||||
{
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
RenderOp op;
|
||||
op.op = OP_CHANGE_BORDER_COLOR;
|
||||
rgba_to_float (color, op.border.color);
|
||||
|
||||
if (memcmp (&op.border.color, &builder->current_program_state->border.color,
|
||||
if (memcmp (&op.border.color, ¤t_program_state->border.color,
|
||||
sizeof (float) * 4) == 0)
|
||||
return;
|
||||
|
||||
rgba_to_float (color, builder->current_program_state->border.color);
|
||||
rgba_to_float (color, current_program_state->border.color);
|
||||
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
}
|
||||
|
||||
@@ -258,8 +258,6 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
ProgramState program_state[GL_N_PROGRAMS];
|
||||
/* Current global state */
|
||||
ProgramState *current_program_state;
|
||||
const Program *current_program;
|
||||
int current_render_target;
|
||||
int current_texture;
|
||||
|
||||
@@ -1966,14 +1966,14 @@ gsk_transform_node_diff (GskRenderNode *node1,
|
||||
cairo_region_t *tmp = cairo_region_copy (sub);
|
||||
cairo_region_translate (tmp, 1, 0);
|
||||
cairo_region_union (sub, tmp);
|
||||
cairo_region_destroy (sub);
|
||||
cairo_region_destroy (tmp);
|
||||
}
|
||||
if (floor (dy) != dy)
|
||||
{
|
||||
cairo_region_t *tmp = cairo_region_copy (sub);
|
||||
cairo_region_translate (tmp, 0, 1);
|
||||
cairo_region_union (sub, tmp);
|
||||
cairo_region_destroy (sub);
|
||||
cairo_region_destroy (tmp);
|
||||
}
|
||||
cairo_region_union (region, sub);
|
||||
cairo_region_destroy (sub);
|
||||
|
||||
@@ -94,6 +94,7 @@ parse_texture (GtkCssParser *parser,
|
||||
if (bytes)
|
||||
{
|
||||
stream = g_memory_input_stream_new_from_bytes (bytes);
|
||||
g_bytes_unref (bytes);
|
||||
pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, &error);
|
||||
g_object_unref (stream);
|
||||
if (pixbuf != NULL)
|
||||
@@ -748,6 +749,8 @@ parse_glyphs (GtkCssParser *parser,
|
||||
pango_glyph_string_set_size (glyph_string, glyph_string->num_glyphs + 1);
|
||||
glyph_string->glyphs[glyph_string->num_glyphs - 1] = gi;
|
||||
}
|
||||
|
||||
g_free (s);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -119,12 +119,17 @@ gsk_vulkan_color_text_pipeline_collect_vertex_data (GskVulkanColorTextPipeline *
|
||||
|
||||
if (gi->glyph != PANGO_GLYPH_EMPTY)
|
||||
{
|
||||
double cx = (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
|
||||
double cy = (double)(gi->geometry.y_offset) / PANGO_SCALE;
|
||||
double cx = (x_position + gi->geometry.x_offset) / PANGO_SCALE;
|
||||
double cy = gi->geometry.y_offset / PANGO_SCALE;
|
||||
GskVulkanColorTextInstance *instance = &instances[count];
|
||||
GskVulkanCachedGlyph *glyph;
|
||||
|
||||
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer, font, gi->glyph, scale);
|
||||
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer,
|
||||
font,
|
||||
gi->glyph,
|
||||
x_position + gi->geometry.x_offset,
|
||||
gi->geometry.y_offset,
|
||||
scale);
|
||||
|
||||
instance->tex_rect[0] = glyph->tx;
|
||||
instance->tex_rect[1] = glyph->ty;
|
||||
|
||||
@@ -115,6 +115,8 @@ gsk_vulkan_glyph_cache_class_init (GskVulkanGlyphCacheClass *klass)
|
||||
typedef struct {
|
||||
PangoFont *font;
|
||||
PangoGlyph glyph;
|
||||
guint xshift;
|
||||
guint yshift;
|
||||
guint scale; /* times 1024 */
|
||||
} GlyphCacheKey;
|
||||
|
||||
@@ -126,6 +128,8 @@ glyph_cache_equal (gconstpointer v1, gconstpointer v2)
|
||||
|
||||
return key1->font == key2->font &&
|
||||
key1->glyph == key2->glyph &&
|
||||
key1->xshift == key2->xshift &&
|
||||
key1->yshift == key2->yshift &&
|
||||
key1->scale == key2->scale;
|
||||
}
|
||||
|
||||
@@ -134,7 +138,7 @@ glyph_cache_hash (gconstpointer v)
|
||||
{
|
||||
const GlyphCacheKey *key = v;
|
||||
|
||||
return GPOINTER_TO_UINT (key->font) ^ key->glyph ^ key->scale;
|
||||
return GPOINTER_TO_UINT (key->font) ^ key->glyph ^ (key->xshift << 24) ^ (key->yshift << 26) ^ key->scale;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -267,10 +271,10 @@ render_glyph (Atlas *atlas,
|
||||
gi.glyph = key->glyph;
|
||||
gi.geometry.width = value->draw_width * 1024;
|
||||
if (key->glyph & PANGO_GLYPH_UNKNOWN_FLAG)
|
||||
gi.geometry.x_offset = 0;
|
||||
gi.geometry.x_offset = key->xshift * 256;
|
||||
else
|
||||
gi.geometry.x_offset = - value->draw_x * 1024;
|
||||
gi.geometry.y_offset = - value->draw_y * 1024;
|
||||
gi.geometry.x_offset = key->xshift * 256 - value->draw_x * 1024;
|
||||
gi.geometry.y_offset = key->yshift * 256 - value->draw_y * 1024;
|
||||
|
||||
glyphs.num_glyphs = 1;
|
||||
glyphs.glyphs = &gi;
|
||||
@@ -328,18 +332,29 @@ gsk_vulkan_glyph_cache_new (GskRenderer *renderer,
|
||||
return cache;
|
||||
}
|
||||
|
||||
#define PHASE(x) ((x % PANGO_SCALE) * 4 / PANGO_SCALE)
|
||||
|
||||
GskVulkanCachedGlyph *
|
||||
gsk_vulkan_glyph_cache_lookup (GskVulkanGlyphCache *cache,
|
||||
gboolean create,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph,
|
||||
int x,
|
||||
int y,
|
||||
float scale)
|
||||
{
|
||||
GlyphCacheKey lookup_key;
|
||||
GskVulkanCachedGlyph *value;
|
||||
guint xshift;
|
||||
guint yshift;
|
||||
|
||||
xshift = PHASE (x);
|
||||
yshift = PHASE (y);
|
||||
|
||||
lookup_key.font = font;
|
||||
lookup_key.glyph = glyph;
|
||||
lookup_key.xshift = xshift;
|
||||
lookup_key.yshift = yshift;
|
||||
lookup_key.scale = (guint)(scale * 1024);
|
||||
|
||||
value = g_hash_table_lookup (cache->hash_table, &lookup_key);
|
||||
@@ -374,6 +389,8 @@ gsk_vulkan_glyph_cache_lookup (GskVulkanGlyphCache *cache,
|
||||
|
||||
key->font = g_object_ref (font);
|
||||
key->glyph = glyph;
|
||||
key->xshift = xshift;
|
||||
key->yshift = yshift;
|
||||
key->scale = (guint)(scale * 1024);
|
||||
|
||||
if (ink_rect.width > 0 && ink_rect.height > 0)
|
||||
|
||||
@@ -22,6 +22,9 @@ GskVulkanCachedGlyph *gsk_vulkan_glyph_cache_lookup (GskVulkanGlyphCache
|
||||
gboolean create,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph,
|
||||
int x,
|
||||
int y,
|
||||
|
||||
float scale);
|
||||
|
||||
void gsk_vulkan_glyph_cache_begin_frame (GskVulkanGlyphCache *cache);
|
||||
|
||||
@@ -362,15 +362,6 @@ gsk_vulkan_renderer_ref_texture_image (GskVulkanRenderer *self,
|
||||
return image;
|
||||
}
|
||||
|
||||
guint
|
||||
gsk_vulkan_renderer_cache_glyph (GskVulkanRenderer *self,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph,
|
||||
float scale)
|
||||
{
|
||||
return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, TRUE, font, glyph, scale)->texture_index;
|
||||
}
|
||||
|
||||
GskVulkanImage *
|
||||
gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *self,
|
||||
GskVulkanUploader *uploader,
|
||||
@@ -379,13 +370,26 @@ gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *self,
|
||||
return g_object_ref (gsk_vulkan_glyph_cache_get_glyph_image (self->glyph_cache, uploader, index));
|
||||
}
|
||||
|
||||
guint
|
||||
gsk_vulkan_renderer_cache_glyph (GskVulkanRenderer *self,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph,
|
||||
int x,
|
||||
int y,
|
||||
float scale)
|
||||
{
|
||||
return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, TRUE, font, glyph, x, y, scale)->texture_index;
|
||||
}
|
||||
|
||||
GskVulkanCachedGlyph *
|
||||
gsk_vulkan_renderer_get_cached_glyph (GskVulkanRenderer *self,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph,
|
||||
int x,
|
||||
int y,
|
||||
float scale)
|
||||
{
|
||||
return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, FALSE, font, glyph, scale);
|
||||
return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, FALSE, font, glyph, x, y, scale);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,6 +30,8 @@ typedef struct
|
||||
guint gsk_vulkan_renderer_cache_glyph (GskVulkanRenderer *renderer,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph,
|
||||
int x,
|
||||
int y,
|
||||
float scale);
|
||||
|
||||
GskVulkanImage * gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *self,
|
||||
@@ -39,6 +41,8 @@ GskVulkanImage * gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *
|
||||
GskVulkanCachedGlyph * gsk_vulkan_renderer_get_cached_glyph (GskVulkanRenderer *self,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph,
|
||||
int x,
|
||||
int y,
|
||||
float scale);
|
||||
|
||||
|
||||
|
||||
@@ -370,6 +370,7 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
|
||||
int i;
|
||||
guint count;
|
||||
guint texture_index;
|
||||
gint x_position;
|
||||
GskVulkanRenderer *renderer = GSK_VULKAN_RENDERER (gsk_vulkan_render_get_renderer (render));
|
||||
|
||||
if (font_has_color_glyphs (font))
|
||||
@@ -402,11 +403,17 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
|
||||
op.text.texture_index = G_MAXUINT;
|
||||
op.text.scale = self->scale_factor;
|
||||
|
||||
x_position = 0;
|
||||
for (i = 0, count = 0; i < num_glyphs; i++)
|
||||
{
|
||||
const PangoGlyphInfo *gi = &glyphs[i];
|
||||
|
||||
texture_index = gsk_vulkan_renderer_cache_glyph (renderer, (PangoFont *)font, gi->glyph, op.text.scale);
|
||||
texture_index = gsk_vulkan_renderer_cache_glyph (renderer,
|
||||
(PangoFont *)font,
|
||||
gi->glyph,
|
||||
x_position + gi->geometry.x_offset,
|
||||
gi->geometry.y_offset,
|
||||
op.text.scale);
|
||||
if (op.text.texture_index == G_MAXUINT)
|
||||
op.text.texture_index = texture_index;
|
||||
if (texture_index != op.text.texture_index)
|
||||
@@ -421,6 +428,8 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
|
||||
}
|
||||
else
|
||||
count++;
|
||||
|
||||
x_position += gi->geometry.width;
|
||||
}
|
||||
|
||||
if (op.text.texture_index != G_MAXUINT && count != 0)
|
||||
|
||||
@@ -127,12 +127,17 @@ gsk_vulkan_text_pipeline_collect_vertex_data (GskVulkanTextPipeline *pipeline,
|
||||
|
||||
if (gi->glyph != PANGO_GLYPH_EMPTY)
|
||||
{
|
||||
double cx = (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
|
||||
double cy = (double)(gi->geometry.y_offset) / PANGO_SCALE;
|
||||
double cx = (x_position + gi->geometry.x_offset) / PANGO_SCALE;
|
||||
double cy = gi->geometry.y_offset / PANGO_SCALE;
|
||||
GskVulkanTextInstance *instance = &instances[count];
|
||||
GskVulkanCachedGlyph *glyph;
|
||||
|
||||
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer, font, gi->glyph, scale);
|
||||
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer,
|
||||
font,
|
||||
gi->glyph,
|
||||
x_position + gi->geometry.x_offset,
|
||||
gi->geometry.y_offset,
|
||||
scale);
|
||||
|
||||
instance->tex_rect[0] = glyph->tx;
|
||||
instance->tex_rect[1] = glyph->ty;
|
||||
|
||||
@@ -128,6 +128,37 @@
|
||||
fun:epoxy_glReadPixels_global_rewrite_ptr
|
||||
}
|
||||
|
||||
{
|
||||
epoxy glxQueryServerString 1
|
||||
Memcheck:Leak
|
||||
fun:malloc
|
||||
fun:XextAddDisplay
|
||||
obj:*
|
||||
obj:*
|
||||
obj:*
|
||||
obj:*
|
||||
obj:*
|
||||
fun:epoxy_glXQueryServerString_global_rewrite_ptr
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
epoxy glxQueryServerString 2
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: definite
|
||||
fun:malloc
|
||||
fun:realpath*
|
||||
obj:*
|
||||
obj:*
|
||||
obj:*
|
||||
obj:*
|
||||
obj:*
|
||||
obj:*
|
||||
obj:*
|
||||
fun:epoxy_glXQueryServerString_global_rewrite_ptr
|
||||
}
|
||||
|
||||
|
||||
# Fontconfig
|
||||
{
|
||||
FcFontSetList
|
||||
@@ -149,6 +180,25 @@
|
||||
fun:FcFontRenderPrepare
|
||||
}
|
||||
|
||||
{
|
||||
FcDefaultSubstitute
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: definite
|
||||
fun:realloc
|
||||
obj:/usr/lib/libfontconfig.so*
|
||||
obj:/usr/lib/libfontconfig.so*
|
||||
fun:FcDefaultSubstitute
|
||||
}
|
||||
|
||||
# Pixman
|
||||
{
|
||||
pixman_image_composite32
|
||||
Memcheck:Cond
|
||||
obj:/usr/lib/libpixman-1.so*
|
||||
obj:/usr/lib/libpixman-1.so*
|
||||
fun:pixman_image_composite32
|
||||
}
|
||||
|
||||
# Pango
|
||||
{
|
||||
pango 1
|
||||
|
||||
+206
-157
@@ -23,41 +23,26 @@
|
||||
#include "gsk/gskrendernodeprivate.h"
|
||||
#include "gskpango.h"
|
||||
#include "gtksnapshotprivate.h"
|
||||
#include "gtkstylecontextprivate.h"
|
||||
#include "gtktextlayoutprivate.h"
|
||||
#include "gtktextviewprivate.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <pango/pango.h>
|
||||
#include <cairo.h>
|
||||
|
||||
#define GSK_PANGO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_PANGO_RENDERER, GskPangoRendererClass))
|
||||
#define GSK_IS_PANGO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_PANGO_RENDERER))
|
||||
#define GSK_PANGO_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_PANGO_RENDERER, GskPangoRendererClass))
|
||||
|
||||
/*
|
||||
* This is a PangoRenderer implementation that translates all the draw calls to
|
||||
* gsk render nodes, using the GtkSnapshot helper class. Glyphs are translated
|
||||
* to text nodes, all other draw calls fall back to cairo nodes.
|
||||
*/
|
||||
|
||||
struct _GskPangoRenderer
|
||||
{
|
||||
PangoRenderer parent_instance;
|
||||
|
||||
GtkSnapshot *snapshot;
|
||||
GdkRGBA fg_color;
|
||||
graphene_rect_t bounds;
|
||||
|
||||
/* house-keeping options */
|
||||
gboolean is_cached_renderer;
|
||||
};
|
||||
|
||||
struct _GskPangoRendererClass
|
||||
{
|
||||
PangoRendererClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GskPangoRenderer, gsk_pango_renderer, PANGO_TYPE_RENDERER)
|
||||
|
||||
void
|
||||
gsk_pango_renderer_set_state (GskPangoRenderer *crenderer,
|
||||
GskPangoRendererState state)
|
||||
{
|
||||
g_return_if_fail (GSK_IS_PANGO_RENDERER (crenderer));
|
||||
|
||||
crenderer->state = state;
|
||||
}
|
||||
|
||||
static void
|
||||
get_color (GskPangoRenderer *crenderer,
|
||||
PangoRenderPart part,
|
||||
@@ -101,16 +86,11 @@ set_color (GskPangoRenderer *crenderer,
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_pango_renderer_show_text_glyphs (PangoRenderer *renderer,
|
||||
const char *text,
|
||||
int text_len,
|
||||
PangoGlyphString *glyphs,
|
||||
cairo_text_cluster_t *clusters,
|
||||
int num_clusters,
|
||||
gboolean backward,
|
||||
PangoFont *font,
|
||||
int x,
|
||||
int y)
|
||||
gsk_pango_renderer_draw_glyph_item (PangoRenderer *renderer,
|
||||
const char *text,
|
||||
PangoGlyphItem *glyph_item,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
|
||||
GdkRGBA color;
|
||||
@@ -118,36 +98,13 @@ gsk_pango_renderer_show_text_glyphs (PangoRenderer *renderer,
|
||||
get_color (crenderer, PANGO_RENDER_PART_FOREGROUND, &color);
|
||||
|
||||
gtk_snapshot_append_text (crenderer->snapshot,
|
||||
font,
|
||||
glyphs,
|
||||
glyph_item->item->analysis.font,
|
||||
glyph_item->glyphs,
|
||||
&color,
|
||||
(float) x / PANGO_SCALE,
|
||||
(float) y / PANGO_SCALE);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_pango_renderer_draw_glyphs (PangoRenderer *renderer,
|
||||
PangoFont *font,
|
||||
PangoGlyphString *glyphs,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
gsk_pango_renderer_show_text_glyphs (renderer, NULL, 0, glyphs, NULL, 0, FALSE, font, x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_pango_renderer_draw_glyph_item (PangoRenderer *renderer,
|
||||
const char *text,
|
||||
PangoGlyphItem *glyph_item,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
PangoFont *font = glyph_item->item->analysis.font;
|
||||
PangoGlyphString *glyphs = glyph_item->glyphs;
|
||||
|
||||
gsk_pango_renderer_show_text_glyphs (renderer, NULL, 0, glyphs, NULL, 0, FALSE, font, x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_pango_renderer_draw_rectangle (PangoRenderer *renderer,
|
||||
PangoRenderPart part,
|
||||
@@ -158,15 +115,14 @@ gsk_pango_renderer_draw_rectangle (PangoRenderer *renderer,
|
||||
{
|
||||
GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
|
||||
GdkRGBA rgba;
|
||||
graphene_rect_t bounds;
|
||||
|
||||
get_color (crenderer, part, &rgba);
|
||||
|
||||
graphene_rect_init (&bounds,
|
||||
(double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
|
||||
(double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
|
||||
|
||||
gtk_snapshot_append_color (crenderer->snapshot, &rgba, &bounds);
|
||||
gtk_snapshot_append_color (crenderer->snapshot,
|
||||
&rgba,
|
||||
&GRAPHENE_RECT_INIT ((double)x / PANGO_SCALE,
|
||||
(double)y / PANGO_SCALE,
|
||||
(double)width / PANGO_SCALE,
|
||||
(double)height / PANGO_SCALE));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -203,78 +159,7 @@ gsk_pango_renderer_draw_trapezoid (PangoRenderer *renderer,
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
/* Draws an error underline that looks like one of:
|
||||
* H E H
|
||||
* /\ /\ /\ /\ /\ -
|
||||
* A/ \ / \ / \ A/ \ / \ |
|
||||
* \ \ / \ / /D \ \ / \ |
|
||||
* \ \/ C \/ / \ \/ C \ | height = HEIGHT_SQUARES * square
|
||||
* \ /\ F / \ F /\ \ |
|
||||
* \ / \ / \ / \ \G |
|
||||
* \ / \ / \ / \ / |
|
||||
* \/ \/ \/ \/ -
|
||||
* B B
|
||||
* |---|
|
||||
* unit_width = (HEIGHT_SQUARES - 1) * square
|
||||
*
|
||||
* The x, y, width, height passed in give the desired bounding box;
|
||||
* x/width are adjusted to make the underline a integer number of units
|
||||
* wide.
|
||||
*/
|
||||
#define HEIGHT_SQUARES 2.5
|
||||
|
||||
static void
|
||||
draw_error_underline (cairo_t *cr,
|
||||
double x,
|
||||
double y,
|
||||
double width,
|
||||
double height)
|
||||
{
|
||||
double square = height / HEIGHT_SQUARES;
|
||||
double unit_width = (HEIGHT_SQUARES - 1) * square;
|
||||
double double_width = 2 * unit_width;
|
||||
int width_units = (width + unit_width / 2) / unit_width;
|
||||
double y_top, y_bottom;
|
||||
double x_left, x_middle, x_right;
|
||||
int i;
|
||||
|
||||
x += (width - width_units * unit_width) / 2;
|
||||
|
||||
y_top = y;
|
||||
y_bottom = y + height;
|
||||
|
||||
/* Bottom of squiggle */
|
||||
x_middle = x + unit_width;
|
||||
x_right = x + double_width;
|
||||
cairo_move_to (cr, x - square / 2, y_top + square / 2); /* A */
|
||||
for (i = 0; i < width_units-2; i += 2)
|
||||
{
|
||||
cairo_line_to (cr, x_middle, y_bottom); /* B */
|
||||
cairo_line_to (cr, x_right, y_top + square); /* C */
|
||||
|
||||
x_middle += double_width;
|
||||
x_right += double_width;
|
||||
}
|
||||
cairo_line_to (cr, x_middle, y_bottom); /* B */
|
||||
|
||||
if (i + 1 == width_units)
|
||||
cairo_line_to (cr, x_middle + square / 2, y_bottom - square / 2); /* G */
|
||||
else if (i + 2 == width_units) {
|
||||
cairo_line_to (cr, x_right + square / 2, y_top + square / 2); /* D */
|
||||
cairo_line_to (cr, x_right, y_top); /* E */
|
||||
}
|
||||
|
||||
/* Top of squiggle */
|
||||
x_left = x_middle - unit_width;
|
||||
for (; i >= 0; i -= 2)
|
||||
{
|
||||
cairo_line_to (cr, x_middle, y_bottom - square); /* F */
|
||||
cairo_line_to (cr, x_left, y_top); /* H */
|
||||
|
||||
x_left -= double_width;
|
||||
x_middle -= double_width;
|
||||
}
|
||||
}
|
||||
#define HEIGHT_RATIO (M_SQRT2/5.0)
|
||||
|
||||
static void
|
||||
gsk_pango_renderer_draw_error_underline (PangoRenderer *renderer,
|
||||
@@ -283,22 +168,61 @@ gsk_pango_renderer_draw_error_underline (PangoRenderer *renderer,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
GdkRGBA rgba;
|
||||
double xx, yy, ww, hh;
|
||||
double hs;
|
||||
double e, o;
|
||||
|
||||
GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
|
||||
cairo_t *cr;
|
||||
|
||||
cr = gtk_snapshot_append_cairo (crenderer->snapshot, &crenderer->bounds);
|
||||
xx = (double)x / PANGO_SCALE;
|
||||
yy = (double)y / PANGO_SCALE;
|
||||
ww = (double)width / PANGO_SCALE;
|
||||
hh = (double)height / PANGO_SCALE;
|
||||
hs = hh / M_SQRT2;
|
||||
|
||||
set_color (crenderer, PANGO_RENDER_PART_UNDERLINE, cr);
|
||||
e = fmod (ww - 2 * hs * HEIGHT_RATIO, hs * (1 - HEIGHT_RATIO));
|
||||
|
||||
cairo_new_path (cr);
|
||||
#if 0
|
||||
gdk_rgba_parse (&rgba, "yellow");
|
||||
gtk_snapshot_append_color (crenderer->snapshot, &rgba,
|
||||
&GRAPHENE_RECT_INIT (xx, yy, ww, hh));
|
||||
#endif
|
||||
|
||||
draw_error_underline (cr,
|
||||
(double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
|
||||
(double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
|
||||
|
||||
cairo_fill (cr);
|
||||
get_color (crenderer, PANGO_RENDER_PART_UNDERLINE, &rgba);
|
||||
gtk_snapshot_save (crenderer->snapshot);
|
||||
gtk_snapshot_translate (crenderer->snapshot,
|
||||
&GRAPHENE_POINT_INIT (xx, yy));
|
||||
|
||||
cairo_destroy (cr);
|
||||
gtk_snapshot_rotate (crenderer->snapshot, 45);
|
||||
gtk_snapshot_translate (crenderer->snapshot,
|
||||
&GRAPHENE_POINT_INIT (e / 2 + hs * HEIGHT_RATIO,
|
||||
- hs * HEIGHT_RATIO));
|
||||
|
||||
xx = yy = o = 0;
|
||||
while (1)
|
||||
{
|
||||
if (o + hs * (1 + HEIGHT_RATIO) >= ww)
|
||||
break;
|
||||
|
||||
gtk_snapshot_append_color (crenderer->snapshot, &rgba,
|
||||
&GRAPHENE_RECT_INIT (xx, yy, hh, hh * HEIGHT_RATIO));
|
||||
|
||||
xx += hh * (1 - HEIGHT_RATIO);
|
||||
yy -= hh * (1 - HEIGHT_RATIO);
|
||||
o += hs * (1 - HEIGHT_RATIO);
|
||||
|
||||
if (o + hs * (1 + HEIGHT_RATIO) >= ww)
|
||||
break;
|
||||
|
||||
gtk_snapshot_append_color (crenderer->snapshot, &rgba,
|
||||
&GRAPHENE_RECT_INIT (xx, yy, hh * HEIGHT_RATIO, hh));
|
||||
|
||||
o += hs * (1 - HEIGHT_RATIO);
|
||||
}
|
||||
|
||||
gtk_snapshot_restore (crenderer->snapshot);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -336,6 +260,124 @@ gsk_pango_renderer_draw_shape (PangoRenderer *renderer,
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
text_renderer_set_rgba (GskPangoRenderer *crenderer,
|
||||
PangoRenderPart part,
|
||||
const GdkRGBA *rgba)
|
||||
{
|
||||
PangoRenderer *renderer = PANGO_RENDERER (crenderer);
|
||||
PangoColor color = { 0, };
|
||||
guint16 alpha;
|
||||
|
||||
if (rgba)
|
||||
{
|
||||
color.red = (guint16)(rgba->red * 65535);
|
||||
color.green = (guint16)(rgba->green * 65535);
|
||||
color.blue = (guint16)(rgba->blue * 65535);
|
||||
alpha = (guint16)(rgba->alpha * 65535);
|
||||
pango_renderer_set_color (renderer, part, &color);
|
||||
pango_renderer_set_alpha (renderer, part, alpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
pango_renderer_set_color (renderer, part, NULL);
|
||||
pango_renderer_set_alpha (renderer, part, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static GtkTextAppearance *
|
||||
get_item_appearance (PangoItem *item)
|
||||
{
|
||||
GSList *tmp_list = item->analysis.extra_attrs;
|
||||
|
||||
while (tmp_list)
|
||||
{
|
||||
PangoAttribute *attr = tmp_list->data;
|
||||
|
||||
if (attr->klass->type == gtk_text_attr_appearance_type)
|
||||
return &((GtkTextAttrAppearance *)attr)->appearance;
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_pango_renderer_prepare_run (PangoRenderer *renderer,
|
||||
PangoLayoutRun *run)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
GskPangoRenderer *crenderer = GSK_PANGO_RENDERER (renderer);
|
||||
GdkRGBA *bg_rgba = NULL;
|
||||
GdkRGBA *fg_rgba = NULL;
|
||||
GtkTextAppearance *appearance;
|
||||
|
||||
PANGO_RENDERER_CLASS (gsk_pango_renderer_parent_class)->prepare_run (renderer, run);
|
||||
|
||||
appearance = get_item_appearance (run->item);
|
||||
|
||||
if (appearance == NULL)
|
||||
return;
|
||||
|
||||
context = gtk_widget_get_style_context (crenderer->widget);
|
||||
|
||||
if (appearance->draw_bg && crenderer->state == GSK_PANGO_RENDERER_NORMAL)
|
||||
bg_rgba = appearance->bg_rgba;
|
||||
else
|
||||
bg_rgba = NULL;
|
||||
|
||||
text_renderer_set_rgba (crenderer, PANGO_RENDER_PART_BACKGROUND, bg_rgba);
|
||||
|
||||
if (crenderer->state == GSK_PANGO_RENDERER_SELECTED &&
|
||||
GTK_IS_TEXT_VIEW (crenderer->widget))
|
||||
{
|
||||
GtkCssNode *selection_node;
|
||||
|
||||
selection_node = gtk_text_view_get_selection_node ((GtkTextView *)crenderer->widget);
|
||||
gtk_style_context_save_to_node (context, selection_node);
|
||||
|
||||
gtk_style_context_get (context,
|
||||
"color", &fg_rgba,
|
||||
NULL);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
}
|
||||
else if (crenderer->state == GSK_PANGO_RENDERER_CURSOR && gtk_widget_has_focus (crenderer->widget))
|
||||
{
|
||||
gtk_style_context_get (context,
|
||||
"background-color", &fg_rgba,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
fg_rgba = appearance->fg_rgba;
|
||||
|
||||
text_renderer_set_rgba (crenderer, PANGO_RENDER_PART_FOREGROUND, fg_rgba);
|
||||
|
||||
if (appearance->strikethrough_rgba)
|
||||
text_renderer_set_rgba (crenderer, PANGO_RENDER_PART_STRIKETHROUGH, appearance->strikethrough_rgba);
|
||||
else
|
||||
text_renderer_set_rgba (crenderer, PANGO_RENDER_PART_STRIKETHROUGH, fg_rgba);
|
||||
|
||||
if (appearance->underline_rgba)
|
||||
text_renderer_set_rgba (crenderer, PANGO_RENDER_PART_UNDERLINE, appearance->underline_rgba);
|
||||
else if (appearance->underline == PANGO_UNDERLINE_ERROR)
|
||||
{
|
||||
if (!crenderer->error_color)
|
||||
{
|
||||
static const GdkRGBA red = { 1, 0, 0, 1 };
|
||||
crenderer->error_color = gdk_rgba_copy (&red);
|
||||
}
|
||||
|
||||
text_renderer_set_rgba (crenderer, PANGO_RENDER_PART_UNDERLINE, crenderer->error_color);
|
||||
}
|
||||
else
|
||||
text_renderer_set_rgba (crenderer, PANGO_RENDER_PART_UNDERLINE, fg_rgba);
|
||||
|
||||
if (fg_rgba != appearance->fg_rgba)
|
||||
gdk_rgba_free (fg_rgba);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_pango_renderer_init (GskPangoRenderer *renderer G_GNUC_UNUSED)
|
||||
{
|
||||
@@ -346,19 +388,19 @@ gsk_pango_renderer_class_init (GskPangoRendererClass *klass)
|
||||
{
|
||||
PangoRendererClass *renderer_class = PANGO_RENDERER_CLASS (klass);
|
||||
|
||||
renderer_class->draw_glyphs = gsk_pango_renderer_draw_glyphs;
|
||||
renderer_class->draw_glyph_item = gsk_pango_renderer_draw_glyph_item;
|
||||
renderer_class->draw_rectangle = gsk_pango_renderer_draw_rectangle;
|
||||
renderer_class->draw_trapezoid = gsk_pango_renderer_draw_trapezoid;
|
||||
renderer_class->draw_error_underline = gsk_pango_renderer_draw_error_underline;
|
||||
renderer_class->draw_shape = gsk_pango_renderer_draw_shape;
|
||||
renderer_class->prepare_run = gsk_pango_renderer_prepare_run;
|
||||
}
|
||||
|
||||
static GskPangoRenderer *cached_renderer = NULL; /* MT-safe */
|
||||
G_LOCK_DEFINE_STATIC (cached_renderer);
|
||||
|
||||
static GskPangoRenderer *
|
||||
acquire_renderer (void)
|
||||
GskPangoRenderer *
|
||||
gsk_pango_renderer_acquire (void)
|
||||
{
|
||||
GskPangoRenderer *renderer;
|
||||
|
||||
@@ -380,13 +422,20 @@ acquire_renderer (void)
|
||||
return renderer;
|
||||
}
|
||||
|
||||
static void
|
||||
release_renderer (GskPangoRenderer *renderer)
|
||||
void
|
||||
gsk_pango_renderer_release (GskPangoRenderer *renderer)
|
||||
{
|
||||
if (G_LIKELY (renderer->is_cached_renderer))
|
||||
{
|
||||
renderer->widget = NULL;
|
||||
renderer->snapshot = NULL;
|
||||
|
||||
if (renderer->error_color)
|
||||
{
|
||||
gdk_rgba_free (renderer->error_color);
|
||||
renderer->error_color = NULL;
|
||||
}
|
||||
|
||||
G_UNLOCK (cached_renderer);
|
||||
}
|
||||
else
|
||||
@@ -414,7 +463,7 @@ gtk_snapshot_append_layout (GtkSnapshot *snapshot,
|
||||
g_return_if_fail (snapshot != NULL);
|
||||
g_return_if_fail (PANGO_IS_LAYOUT (layout));
|
||||
|
||||
crenderer = acquire_renderer ();
|
||||
crenderer = gsk_pango_renderer_acquire ();
|
||||
|
||||
crenderer->snapshot = snapshot;
|
||||
crenderer->fg_color = *color;
|
||||
@@ -424,5 +473,5 @@ gtk_snapshot_append_layout (GtkSnapshot *snapshot,
|
||||
|
||||
pango_renderer_draw_layout (PANGO_RENDERER (crenderer), layout, 0, 0);
|
||||
|
||||
release_renderer (crenderer);
|
||||
gsk_pango_renderer_release (crenderer);
|
||||
}
|
||||
|
||||
+48
-6
@@ -24,15 +24,57 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GSK_TYPE_PANGO_RENDERER (gsk_pango_renderer_get_type ())
|
||||
#define GSK_TYPE_PANGO_RENDERER (gsk_pango_renderer_get_type ())
|
||||
#define GSK_PANGO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_PANGO_RENDERER, GskPangoRenderer))
|
||||
#define GSK_IS_PANGO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_PANGO_RENDERER))
|
||||
#define GSK_PANGO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_PANGO_RENDERER, GskPangoRendererClass))
|
||||
#define GSK_IS_PANGO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_PANGO_RENDERER))
|
||||
#define GSK_PANGO_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_PANGO_RENDERER, GskPangoRendererClass))
|
||||
|
||||
#define GSK_PANGO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_PANGO_RENDERER, GskPangoRenderer))
|
||||
#define GSK_IS_PANGO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_PANGO_RENDERER))
|
||||
typedef struct _GskPangoRenderer GskPangoRenderer;
|
||||
typedef struct _GskPangoRendererClass GskPangoRendererClass;
|
||||
|
||||
typedef struct _GskPangoRenderer GskPangoRenderer;
|
||||
typedef struct _GskPangoRendererClass GskPangoRendererClass;
|
||||
typedef enum
|
||||
{
|
||||
GSK_PANGO_RENDERER_NORMAL,
|
||||
GSK_PANGO_RENDERER_SELECTED,
|
||||
GSK_PANGO_RENDERER_CURSOR
|
||||
} GskPangoRendererState;
|
||||
|
||||
GType gsk_pango_renderer_get_type (void) G_GNUC_CONST;
|
||||
/*
|
||||
* This is a PangoRenderer implementation that translates all the draw calls to
|
||||
* gsk render nodes, using the GtkSnapshot helper class. Glyphs are translated
|
||||
* to text nodes, all other draw calls fall back to cairo nodes.
|
||||
*/
|
||||
|
||||
struct _GskPangoRenderer
|
||||
{
|
||||
PangoRenderer parent_instance;
|
||||
|
||||
GtkWidget *widget;
|
||||
GtkSnapshot *snapshot;
|
||||
GdkRGBA fg_color;
|
||||
graphene_rect_t bounds;
|
||||
|
||||
/* Error underline color for this widget */
|
||||
GdkRGBA *error_color;
|
||||
|
||||
GskPangoRendererState state;
|
||||
|
||||
/* house-keeping options */
|
||||
guint is_cached_renderer : 1;
|
||||
};
|
||||
|
||||
struct _GskPangoRendererClass
|
||||
{
|
||||
PangoRendererClass parent_class;
|
||||
};
|
||||
|
||||
GType gsk_pango_renderer_get_type (void) G_GNUC_CONST;
|
||||
void gsk_pango_renderer_set_state (GskPangoRenderer *crenderer,
|
||||
GskPangoRendererState state);
|
||||
GskPangoRenderer *gsk_pango_renderer_acquire (void);
|
||||
void gsk_pango_renderer_release (GskPangoRenderer *crenderer);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -232,6 +232,7 @@
|
||||
#include <gtk/gtktexttag.h>
|
||||
#include <gtk/gtktexttagtable.h>
|
||||
#include <gtk/gtktextview.h>
|
||||
#include <gtk/gtktimingfunction.h>
|
||||
#include <gtk/gtktogglebutton.h>
|
||||
#include <gtk/gtktoggletoolbutton.h>
|
||||
#include <gtk/gtktoolbar.h>
|
||||
|
||||
@@ -0,0 +1,279 @@
|
||||
/* gtkanimation.c: An animation
|
||||
*
|
||||
* Copyright 2019 GNOME Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gtkanimation
|
||||
* @Title: GtkAnimation
|
||||
* @Short_description: The base class for animations
|
||||
*
|
||||
* ...
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkanimationprivate.h"
|
||||
|
||||
#include "gtkintl.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
|
||||
typedef struct {
|
||||
double duration;
|
||||
double delay;
|
||||
GtkAnimationDirection direction;
|
||||
int repeat_count;
|
||||
gboolean auto_reverse;
|
||||
GtkTimingFunction *timing;
|
||||
} GtkAnimationPrivate;
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GtkAnimation, gtk_animation, G_TYPE_OBJECT)
|
||||
|
||||
enum {
|
||||
PROP_DURATION = 1,
|
||||
PROP_DELAY,
|
||||
PROP_DIRECTION,
|
||||
PROP_REPEAT_COUNT,
|
||||
PROP_AUTO_REVERSE,
|
||||
PROP_TIMING_FUNCTION,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *animation_props[N_PROPS];
|
||||
|
||||
static void
|
||||
gtk_animation_finalize (GObject *gobject)
|
||||
{
|
||||
G_OBJECT_CLASS (gtk_animation_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_animation_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkAnimation *self = GTK_ANIMATION (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DURATION:
|
||||
gtk_animation_set_duration (self, g_value_get_double (value));
|
||||
break;
|
||||
|
||||
case PROP_DELAY:
|
||||
gtk_animation_set_delay (self, g_value_get_double (value));
|
||||
break;
|
||||
|
||||
case PROP_DIRECTION:
|
||||
gtk_animation_set_direction (self, g_value_get_enum (value));
|
||||
break;
|
||||
|
||||
case PROP_REPEAT_COUNT:
|
||||
break;
|
||||
|
||||
case PROP_AUTO_REVERSE:
|
||||
break;
|
||||
|
||||
case PROP_TIMING_FUNCTION:
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_animation_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkAnimation *self = GTK_ANIMATION (gobject);
|
||||
GtkAnimationPrivate *priv = gtk_animation_get_instance_private (self);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DURATION:
|
||||
break;
|
||||
|
||||
case PROP_DELAY:
|
||||
break;
|
||||
|
||||
case PROP_DIRECTION:
|
||||
break;
|
||||
|
||||
case PROP_REPEAT_COUNT:
|
||||
break;
|
||||
|
||||
case PROP_AUTO_REVERSE:
|
||||
break;
|
||||
|
||||
case PROP_TIMING_FUNCTION:
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_animation_class_init (GtkAnimationClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->set_property = gtk_animation_set_property:
|
||||
gobject_class->get_property = gtk_animation_get_property;
|
||||
gobject_class->finalize = gtk_animation_finalize;
|
||||
|
||||
animation_props[PROP_DURATION] =
|
||||
g_param_spec_uint64 ("duration",
|
||||
P_("Duration"),
|
||||
P_("The duration of the animation, in milliseconds"),
|
||||
0, G_MAXUINT64, 0,
|
||||
G_PARAM_READ_WRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
animation_props[PROP_DELAY] =
|
||||
g_param_spec_uint64 ("delay",
|
||||
P_("Delay"),
|
||||
P_("The delay before the animation starts, in milliseconds"),
|
||||
0, G_MAXUINT64, 0,
|
||||
G_PARAM_READ_WRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
animation_props[PROP_DIRECTION] =
|
||||
g_param_spec_enum ("direction",
|
||||
P_("Direction"),
|
||||
P_("The direction of the animation's progress"),
|
||||
GTK_TYPE_ANIMATION_DIRECTION,
|
||||
GTK_ANIMATION_DIRECTION_FORWARD,
|
||||
G_PARAM_READ_WRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
g_object_class_install_properties (gobject_class, N_PROPS, animation_props);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_animation_init (GtkAnimation *self)
|
||||
{
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gtk_animation_advance:
|
||||
* @animation: a #GtkAnimation
|
||||
* @frame_time: the frame time, coming from the frame clock
|
||||
*
|
||||
* Advances the given @animation by @frame_time milliseconds.
|
||||
*/
|
||||
void
|
||||
gtk_animation_advance (GtkAnimation *animation,
|
||||
gint64 frame_time)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
gtk_animation_set_duration (GtkAnimation *animation,
|
||||
guint64 milliseconds)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
guint64
|
||||
gtk_animation_get_duration (GtkAnimation *animation)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
gtk_animation_set_delay (GtkAnimation *animation,
|
||||
double seconds)
|
||||
{
|
||||
}
|
||||
|
||||
double
|
||||
gtk_animation_get_delay (GtkAnimation *animation)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
gtk_animation_set_direction (GtkAnimation *animation,
|
||||
GtkAnimationDirection direction)
|
||||
{
|
||||
}
|
||||
|
||||
GtkAnimationDirection
|
||||
gtk_animation_get_direction (GtkAnimation *animation)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
gtk_animation_set_repeat_count (GtkAnimation *animation,
|
||||
int repeats)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
gtk_animation_get_repeat_count (GtkAnimation *animation)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
gtk_animation_set_auto_reverse (GtkAnimation *animation,
|
||||
gboolean auto_reverse)
|
||||
{
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_animation_get_auto_reverse (GtkAnimation *animation)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
gtk_animation_set_timing_function (GtkAnimation *animation,
|
||||
GtkTimingFunction *function)
|
||||
{
|
||||
}
|
||||
|
||||
GtkTimingFunction *
|
||||
gtk_animation_get_timing_function (GtkAnimation *animation)
|
||||
{
|
||||
}
|
||||
|
||||
double
|
||||
gtk_animation_get_elapsed_time (GtkAnimation *animation)
|
||||
{
|
||||
}
|
||||
|
||||
double
|
||||
gtk_animation_get_progress (GtkAnimation *animation)
|
||||
{
|
||||
}
|
||||
|
||||
double
|
||||
gtk_animation_get_total_duration (GtkAnimation *animation)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
gtk_animation_get_current_repeat (GtkAnimation *animation)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/* gtkanimation.h: A class representing an animation
|
||||
*
|
||||
* Copyright 2019 GNOME Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtktypes.h>
|
||||
#include <gtk/gtkenums.h>
|
||||
#include <gtk/gtktimingfunction.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_ANIMATION (gtk_animation_get_type())
|
||||
|
||||
/**
|
||||
* GtkAnimation:
|
||||
*
|
||||
* A base type for representing an animation.
|
||||
*/
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
G_DECLARE_DERIVABLE_TYPE (GtkAnimation, gtk_animation, GTK, ANIMATION, GObject)
|
||||
|
||||
/**
|
||||
* double:
|
||||
*
|
||||
* A type used to represent elapsed time in seconds.
|
||||
*/
|
||||
typedef double double;
|
||||
|
||||
/* Properties */
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_animation_set_duration (GtkAnimation *animation,
|
||||
double duration);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
double gtk_animation_get_duration (GtkAnimation *animation);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_animation_set_delay (GtkAnimation *animation,
|
||||
double delay);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
double gtk_animation_get_delay (GtkAnimation *animation);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_animation_set_direction (GtkAnimation *animation,
|
||||
GtkAnimationDirection direction);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkAnimationDirection gtk_animation_get_direction (GtkAnimation *animation);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_animation_set_repeat_count (GtkAnimation *animation,
|
||||
int repeats);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
int gtk_animation_get_repeat_count (GtkAnimation *animation);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_animation_set_auto_reverse (GtkAnimation *animation,
|
||||
gboolean auto_reverse);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_animation_get_auto_reverse (GtkAnimation *animation);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_animation_set_timing_function (GtkAnimation *animation,
|
||||
GtkTimingFunction *function);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkTimingFunction * gtk_animation_get_timing_function (GtkAnimation *animation);
|
||||
|
||||
/* State query */
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
double gtk_animation_get_elapsed_time (GtkAnimation *animation);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
double gtk_animation_get_progress (GtkAnimation *animation);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
double gtk_animation_get_total_duration (GtkAnimation *animation);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
int gtk_animation_get_current_repeat (GtkAnimation *animation);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -0,0 +1,37 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkanimationmanagerprivate.h"
|
||||
|
||||
struct _GtkAnimationManager
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GdkFrameClock *frame_clock;
|
||||
|
||||
gint64 last_frame_time;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GtkAnimationManager, gtk_animation_manager, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gtk_animation_manager_class_init (GtkAnimationManagerClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_animation_manager_init (GtkAnimationManager *self)
|
||||
{
|
||||
}
|
||||
|
||||
GtkAnimationManager *
|
||||
gtk_animation_manager_new (void)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_ANIMATION_MANAGER, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_animation_manager_set_frame_clock (GtkAnimationManager *self,
|
||||
GdkFrameClock *frame_clock)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/* gtkanimationmanagerprivate.h: Animation manager
|
||||
*
|
||||
* Copyright 2019 GNOME Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtktypes.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_ANIMATION_MANAGER (gtk_animation_manager_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GtkAnimationManager, gtk_animation_manager, GTK, ANIMATION_MANAGER, GObject)
|
||||
|
||||
GtkAnimationManager *
|
||||
gtk_animation_manager_new (void);
|
||||
|
||||
void
|
||||
gtk_animation_manager_set_frame_clock (GtkAnimationManager *self,
|
||||
GdkFrameClock *frame_clock);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -0,0 +1,41 @@
|
||||
/* gtkanimationprivate.h: Animation type
|
||||
*
|
||||
* Copyright 2019 GNOME Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "gtkanimation.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
struct _GtkAnimationClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* start) (GtkAnimation *animation);
|
||||
void (* advance) (GtkAnimation *animation,
|
||||
gint64 frame_time);
|
||||
void (* stop) (GtkAnimation *animation,
|
||||
gboolean is_finished);
|
||||
void (* iteration) (GtkAnimation *animation);
|
||||
};
|
||||
|
||||
void gtk_animation_advance (GtkAnimation *animation,
|
||||
gint64 frame_time);
|
||||
|
||||
G_END_DECLS
|
||||
+15
-36
@@ -1604,8 +1604,9 @@ get_size (GtkCellRenderer *cell,
|
||||
GtkCellRendererText *celltext = GTK_CELL_RENDERER_TEXT (cell);
|
||||
GtkCellRendererTextPrivate *priv = gtk_cell_renderer_text_get_instance_private (celltext);
|
||||
PangoRectangle rect;
|
||||
gint xpad, ypad;
|
||||
gint cell_width, cell_height;
|
||||
int xpad, ypad;
|
||||
int cell_width, cell_height;
|
||||
float xalign, yalign;
|
||||
|
||||
gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
|
||||
|
||||
@@ -1652,52 +1653,30 @@ get_size (GtkCellRenderer *cell,
|
||||
if (width == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
if (layout)
|
||||
g_object_ref (layout);
|
||||
else
|
||||
layout = get_layout (celltext, widget, NULL, 0);
|
||||
|
||||
pango_layout_get_pixel_extents (layout, NULL, &rect);
|
||||
|
||||
if (cell_area)
|
||||
{
|
||||
gfloat xalign, yalign;
|
||||
gtk_cell_renderer_get_alignment (cell, &xalign, &yalign);
|
||||
|
||||
gtk_cell_renderer_get_alignment (cell, &xalign, &yalign);
|
||||
rect.height = MIN (rect.height, cell_area->height - 2 * ypad);
|
||||
rect.width = MIN (rect.width, cell_area->width - 2 * xpad);
|
||||
|
||||
rect.height = MIN (rect.height, cell_area->height - 2 * ypad);
|
||||
rect.width = MIN (rect.width, cell_area->width - 2 * xpad);
|
||||
|
||||
if (x_offset)
|
||||
{
|
||||
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
|
||||
*x_offset = (1.0 - xalign) * (cell_area->width - (rect.width + (2 * xpad)));
|
||||
else
|
||||
*x_offset = xalign * (cell_area->width - (rect.width + (2 * xpad)));
|
||||
|
||||
if ((priv->ellipsize_set && priv->ellipsize != PANGO_ELLIPSIZE_NONE) || priv->wrap_width != -1)
|
||||
*x_offset = MAX(*x_offset, 0);
|
||||
}
|
||||
if (y_offset)
|
||||
{
|
||||
*y_offset = yalign * (cell_area->height - (rect.height + (2 * ypad)));
|
||||
*y_offset = MAX (*y_offset, 0);
|
||||
}
|
||||
}
|
||||
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
|
||||
*x_offset = (1.0 - xalign) * (cell_area->width - (rect.width + (2 * xpad)));
|
||||
else
|
||||
{
|
||||
if (x_offset) *x_offset = 0;
|
||||
if (y_offset) *y_offset = 0;
|
||||
}
|
||||
*x_offset = xalign * (cell_area->width - (rect.width + (2 * xpad)));
|
||||
|
||||
if ((priv->ellipsize_set && priv->ellipsize != PANGO_ELLIPSIZE_NONE) || priv->wrap_width != -1)
|
||||
*x_offset = MAX(*x_offset, 0);
|
||||
|
||||
*y_offset = yalign * (cell_area->height - (rect.height + (2 * ypad)));
|
||||
*y_offset = MAX (*y_offset, 0);
|
||||
|
||||
if (height)
|
||||
*height = ypad * 2 + rect.height;
|
||||
|
||||
if (width)
|
||||
*width = xpad * 2 + rect.width;
|
||||
|
||||
g_object_unref (layout);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -580,7 +580,7 @@ gtk_combo_box_text_remove_all (GtkComboBoxText *combo_box)
|
||||
* function will return its contents (which will not necessarily
|
||||
* be an item from the list).
|
||||
*
|
||||
* Returns: (transfer full): a newly allocated string containing the
|
||||
* Returns: (nullable) (transfer full): a newly allocated string containing the
|
||||
* currently active text. Must be freed with g_free().
|
||||
*/
|
||||
gchar *
|
||||
|
||||
+15
-264
@@ -18,34 +18,19 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkcsseasevalueprivate.h"
|
||||
#include "gtktimingfunctionprivate.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
typedef enum {
|
||||
GTK_CSS_EASE_CUBIC_BEZIER,
|
||||
GTK_CSS_EASE_STEPS
|
||||
} GtkCssEaseType;
|
||||
|
||||
struct _GtkCssValue {
|
||||
GTK_CSS_VALUE_BASE
|
||||
GtkCssEaseType type;
|
||||
union {
|
||||
struct {
|
||||
double x1;
|
||||
double y1;
|
||||
double x2;
|
||||
double y2;
|
||||
} cubic;
|
||||
struct {
|
||||
guint steps;
|
||||
gboolean start;
|
||||
} steps;
|
||||
} u;
|
||||
GtkTimingFunction *tm;
|
||||
};
|
||||
|
||||
static void
|
||||
gtk_css_value_ease_free (GtkCssValue *value)
|
||||
{
|
||||
gtk_timing_function_unref (value->tm);
|
||||
g_slice_free (GtkCssValue, value);
|
||||
}
|
||||
|
||||
@@ -63,23 +48,7 @@ static gboolean
|
||||
gtk_css_value_ease_equal (const GtkCssValue *ease1,
|
||||
const GtkCssValue *ease2)
|
||||
{
|
||||
if (ease1->type != ease2->type)
|
||||
return FALSE;
|
||||
|
||||
switch (ease1->type)
|
||||
{
|
||||
case GTK_CSS_EASE_CUBIC_BEZIER:
|
||||
return ease1->u.cubic.x1 == ease2->u.cubic.x1 &&
|
||||
ease1->u.cubic.y1 == ease2->u.cubic.y1 &&
|
||||
ease1->u.cubic.x2 == ease2->u.cubic.x2 &&
|
||||
ease1->u.cubic.y2 == ease2->u.cubic.y2;
|
||||
case GTK_CSS_EASE_STEPS:
|
||||
return ease1->u.steps.steps == ease2->u.steps.steps &&
|
||||
ease1->u.steps.start == ease2->u.steps.start;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return FALSE;
|
||||
}
|
||||
return gtk_timing_function_equal (ease1->tm, ease2->tm);
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
@@ -95,43 +64,7 @@ static void
|
||||
gtk_css_value_ease_print (const GtkCssValue *ease,
|
||||
GString *string)
|
||||
{
|
||||
switch (ease->type)
|
||||
{
|
||||
case GTK_CSS_EASE_CUBIC_BEZIER:
|
||||
if (ease->u.cubic.x1 == 0.25 && ease->u.cubic.y1 == 0.1 &&
|
||||
ease->u.cubic.x2 == 0.25 && ease->u.cubic.y2 == 1.0)
|
||||
g_string_append (string, "ease");
|
||||
else if (ease->u.cubic.x1 == 0.0 && ease->u.cubic.y1 == 0.0 &&
|
||||
ease->u.cubic.x2 == 1.0 && ease->u.cubic.y2 == 1.0)
|
||||
g_string_append (string, "linear");
|
||||
else if (ease->u.cubic.x1 == 0.42 && ease->u.cubic.y1 == 0.0 &&
|
||||
ease->u.cubic.x2 == 1.0 && ease->u.cubic.y2 == 1.0)
|
||||
g_string_append (string, "ease-in");
|
||||
else if (ease->u.cubic.x1 == 0.0 && ease->u.cubic.y1 == 0.0 &&
|
||||
ease->u.cubic.x2 == 0.58 && ease->u.cubic.y2 == 1.0)
|
||||
g_string_append (string, "ease-out");
|
||||
else if (ease->u.cubic.x1 == 0.42 && ease->u.cubic.y1 == 0.0 &&
|
||||
ease->u.cubic.x2 == 0.58 && ease->u.cubic.y2 == 1.0)
|
||||
g_string_append (string, "ease-in-out");
|
||||
else
|
||||
g_string_append_printf (string, "cubic-bezier(%g,%g,%g,%g)",
|
||||
ease->u.cubic.x1, ease->u.cubic.y1,
|
||||
ease->u.cubic.x2, ease->u.cubic.y2);
|
||||
break;
|
||||
case GTK_CSS_EASE_STEPS:
|
||||
if (ease->u.steps.steps == 1)
|
||||
{
|
||||
g_string_append (string, ease->u.steps.start ? "step-start" : "step-end");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_string_append_printf (string, "steps(%u%s)", ease->u.steps.steps, ease->u.steps.start ? ",start" : "");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
gtk_timing_function_print (ease->tm, string);
|
||||
}
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_EASE = {
|
||||
@@ -145,42 +78,12 @@ static const GtkCssValueClass GTK_CSS_VALUE_EASE = {
|
||||
};
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_ease_value_new_cubic_bezier (double x1,
|
||||
double y1,
|
||||
double x2,
|
||||
double y2)
|
||||
_gtk_css_ease_value_new_ease (void)
|
||||
{
|
||||
GtkCssValue *value;
|
||||
|
||||
g_return_val_if_fail (x1 >= 0.0, NULL);
|
||||
g_return_val_if_fail (x1 <= 1.0, NULL);
|
||||
g_return_val_if_fail (x2 >= 0.0, NULL);
|
||||
g_return_val_if_fail (x2 <= 1.0, NULL);
|
||||
|
||||
value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_EASE);
|
||||
|
||||
value->type = GTK_CSS_EASE_CUBIC_BEZIER;
|
||||
value->u.cubic.x1 = x1;
|
||||
value->u.cubic.y1 = y1;
|
||||
value->u.cubic.x2 = x2;
|
||||
value->u.cubic.y2 = y2;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
_gtk_css_ease_value_new_steps (guint n_steps,
|
||||
gboolean start)
|
||||
{
|
||||
GtkCssValue *value;
|
||||
|
||||
g_return_val_if_fail (n_steps > 0, NULL);
|
||||
|
||||
value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_EASE);
|
||||
|
||||
value->type = GTK_CSS_EASE_STEPS;
|
||||
value->u.steps.steps = n_steps;
|
||||
value->u.steps.start = start;
|
||||
value->tm = gtk_ease ();
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -224,131 +127,19 @@ _gtk_css_ease_value_can_parse (GtkCssParser *parser)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static guint
|
||||
gtk_css_ease_value_parse_cubic_bezier_arg (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data)
|
||||
{
|
||||
double *values = data;
|
||||
|
||||
if (!gtk_css_parser_consume_number (parser, &values[arg]))
|
||||
return 0;
|
||||
|
||||
if (arg % 2 == 0)
|
||||
{
|
||||
if (values[arg] < 0 || values[arg] > 1.0)
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "value %g out of range. Must be from 0.0 to 1.0", values[arg]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_ease_value_parse_cubic_bezier (GtkCssParser *parser)
|
||||
{
|
||||
double values[4];
|
||||
|
||||
if (!gtk_css_parser_consume_function (parser, 4, 4, gtk_css_ease_value_parse_cubic_bezier_arg, values))
|
||||
return NULL;
|
||||
|
||||
return _gtk_css_ease_value_new_cubic_bezier (values[0], values[1], values[2], values[3]);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int n_steps;
|
||||
gboolean start;
|
||||
} ParseStepsData;
|
||||
|
||||
static guint
|
||||
gtk_css_ease_value_parse_steps_arg (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data_)
|
||||
{
|
||||
ParseStepsData *data = data_;
|
||||
|
||||
switch (arg)
|
||||
{
|
||||
case 0:
|
||||
if (!gtk_css_parser_consume_integer (parser, &data->n_steps))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (data->n_steps < 1)
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "Number of steps must be > 0");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
||||
case 1:
|
||||
if (gtk_css_parser_try_ident (parser, "start"))
|
||||
data->start = TRUE;
|
||||
else if (gtk_css_parser_try_ident (parser, "end"))
|
||||
data->start = FALSE;
|
||||
else
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Only allowed values are 'start' and 'end'");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
||||
default:
|
||||
g_return_val_if_reached (0);
|
||||
}
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_ease_value_parse_steps (GtkCssParser *parser)
|
||||
{
|
||||
ParseStepsData data = { 0, FALSE };
|
||||
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 2, gtk_css_ease_value_parse_steps_arg, &data))
|
||||
return NULL;
|
||||
|
||||
return _gtk_css_ease_value_new_steps (data.n_steps, data.start);
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_ease_value_parse (GtkCssParser *parser)
|
||||
{
|
||||
guint i;
|
||||
GtkCssValue *value;
|
||||
GtkTimingFunction *tm;
|
||||
|
||||
g_return_val_if_fail (parser != NULL, NULL);
|
||||
if (!gtk_timing_function_parser_parse (parser, &tm))
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (parser_values); i++)
|
||||
{
|
||||
if (parser_values[i].is_function)
|
||||
{
|
||||
if (gtk_css_parser_has_function (parser, parser_values[i].name))
|
||||
{
|
||||
if (parser_values[i].is_bezier)
|
||||
return gtk_css_ease_value_parse_cubic_bezier (parser);
|
||||
else
|
||||
return gtk_css_ease_value_parse_steps (parser);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gtk_css_parser_try_ident (parser, parser_values[i].name))
|
||||
{
|
||||
if (parser_values[i].is_bezier)
|
||||
return _gtk_css_ease_value_new_cubic_bezier (parser_values[i].values[0],
|
||||
parser_values[i].values[1],
|
||||
parser_values[i].values[2],
|
||||
parser_values[i].values[3]);
|
||||
else
|
||||
return _gtk_css_ease_value_new_steps (parser_values[i].values[0],
|
||||
parser_values[i].values[1] != 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_EASE);
|
||||
value->tm = tm;
|
||||
|
||||
gtk_css_parser_error_syntax (parser, "Expected a valid ease value");
|
||||
return NULL;
|
||||
return value;
|
||||
}
|
||||
|
||||
double
|
||||
@@ -362,45 +153,5 @@ _gtk_css_ease_value_transform (const GtkCssValue *ease,
|
||||
if (progress >= 1)
|
||||
return 1;
|
||||
|
||||
switch (ease->type)
|
||||
{
|
||||
case GTK_CSS_EASE_CUBIC_BEZIER:
|
||||
{
|
||||
static const double epsilon = 0.00001;
|
||||
double tmin, t, tmax;
|
||||
|
||||
tmin = 0.0;
|
||||
tmax = 1.0;
|
||||
t = progress;
|
||||
|
||||
while (tmin < tmax)
|
||||
{
|
||||
double sample;
|
||||
sample = (((1.0 + 3 * ease->u.cubic.x1 - 3 * ease->u.cubic.x2) * t
|
||||
+ -6 * ease->u.cubic.x1 + 3 * ease->u.cubic.x2) * t
|
||||
+ 3 * ease->u.cubic.x1 ) * t;
|
||||
if (fabs(sample - progress) < epsilon)
|
||||
break;
|
||||
|
||||
if (progress > sample)
|
||||
tmin = t;
|
||||
else
|
||||
tmax = t;
|
||||
t = (tmax + tmin) * .5;
|
||||
}
|
||||
|
||||
return (((1.0 + 3 * ease->u.cubic.y1 - 3 * ease->u.cubic.y2) * t
|
||||
+ -6 * ease->u.cubic.y1 + 3 * ease->u.cubic.y2) * t
|
||||
+ 3 * ease->u.cubic.y1 ) * t;
|
||||
}
|
||||
case GTK_CSS_EASE_STEPS:
|
||||
progress *= ease->u.steps.steps;
|
||||
progress = floor (progress) + (ease->u.steps.start ? 0 : 1);
|
||||
return progress / ease->u.steps.steps;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return 1.0;
|
||||
}
|
||||
return gtk_timing_function_transform_time (ease->tm, progress, 1.0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -25,10 +25,7 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GtkCssValue * _gtk_css_ease_value_new_cubic_bezier (double x1,
|
||||
double y1,
|
||||
double x2,
|
||||
double y2);
|
||||
GtkCssValue * _gtk_css_ease_value_new_ease (void);
|
||||
gboolean _gtk_css_ease_value_can_parse (GtkCssParser *parser);
|
||||
GtkCssValue * _gtk_css_ease_value_parse (GtkCssParser *parser);
|
||||
|
||||
|
||||
@@ -1613,8 +1613,7 @@ _gtk_css_style_property_init_properties (void)
|
||||
0,
|
||||
transition_timing_function_parse,
|
||||
NULL,
|
||||
_gtk_css_array_value_new (
|
||||
_gtk_css_ease_value_new_cubic_bezier (0.25, 0.1, 0.25, 1.0)));
|
||||
_gtk_css_array_value_new (_gtk_css_ease_value_new_ease ()));
|
||||
gtk_css_style_property_register ("transition-delay",
|
||||
GTK_CSS_PROPERTY_TRANSITION_DELAY,
|
||||
G_TYPE_NONE,
|
||||
@@ -1647,8 +1646,7 @@ _gtk_css_style_property_init_properties (void)
|
||||
0,
|
||||
transition_timing_function_parse,
|
||||
NULL,
|
||||
_gtk_css_array_value_new (
|
||||
_gtk_css_ease_value_new_cubic_bezier (0.25, 0.1, 0.25, 1.0)));
|
||||
_gtk_css_array_value_new (_gtk_css_ease_value_new_ease ()));
|
||||
gtk_css_style_property_register ("animation-iteration-count",
|
||||
GTK_CSS_PROPERTY_ANIMATION_ITERATION_COUNT,
|
||||
G_TYPE_NONE,
|
||||
|
||||
@@ -1529,6 +1529,7 @@ gtk_entry_measure (GtkWidget *widget,
|
||||
{
|
||||
GtkEntry *entry = GTK_ENTRY (widget);
|
||||
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
|
||||
int i;
|
||||
|
||||
gtk_widget_measure (priv->text,
|
||||
orientation,
|
||||
@@ -1536,6 +1537,30 @@ gtk_entry_measure (GtkWidget *widget,
|
||||
minimum, natural,
|
||||
minimum_baseline, natural_baseline);
|
||||
|
||||
for (i = 0; i < MAX_ICONS; i++)
|
||||
{
|
||||
EntryIconInfo *icon_info = priv->icons[i];
|
||||
int icon_min, icon_nat;
|
||||
|
||||
if (!icon_info)
|
||||
continue;
|
||||
|
||||
gtk_widget_measure (icon_info->widget,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
-1, &icon_min, &icon_nat, NULL, NULL);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
*minimum += icon_min;
|
||||
*natural += icon_nat;
|
||||
}
|
||||
else
|
||||
{
|
||||
*minimum = MAX (*minimum, icon_min);
|
||||
*natural = MAX (*natural, icon_nat);
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->progress_widget && gtk_widget_get_visible (priv->progress_widget))
|
||||
{
|
||||
int prog_min, prog_nat;
|
||||
|
||||
@@ -1147,4 +1147,26 @@ typedef enum {
|
||||
GTK_CONSTRAINT_VFL_PARSER_ERROR_INVALID_RELATION
|
||||
} GtkConstraintVflParserError;
|
||||
|
||||
/**
|
||||
* GtkAnimationDirection:
|
||||
* @GTK_ANIMATION_DIRECTION_FORWARD:
|
||||
* @GTK_ANIMATION_DIRECTION_BACKWARD:
|
||||
*
|
||||
* The direction of the animation.
|
||||
*/
|
||||
typedef enum {
|
||||
GTK_ANIMATION_DIRECTION_FORWARD,
|
||||
GTK_ANIMATION_DIRECTION_BACKWARD
|
||||
} GtkAnimationDirection;
|
||||
|
||||
typedef enum {
|
||||
GTK_STEP_POSITION_JUMP_START,
|
||||
GTK_STEP_POSITION_JUMP_END,
|
||||
GTK_STEP_POSITION_JUMP_NONE,
|
||||
GTK_STEP_POSITION_JUMP_BOTH,
|
||||
|
||||
GTK_STEP_POSITION_START = GTK_STEP_POSITION_JUMP_START,
|
||||
GTK_STEP_POSITION_END = GTK_STEP_POSITION_JUMP_END
|
||||
} GtkStepPosition;
|
||||
|
||||
#endif /* __GTK_ENUMS_H__ */
|
||||
|
||||
@@ -577,9 +577,34 @@ gtk_file_chooser_dialog_map (GtkWidget *widget)
|
||||
GTK_WIDGET_CLASS (gtk_file_chooser_dialog_parent_class)->map (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
save_dialog_geometry (GtkFileChooserDialog *dialog)
|
||||
{
|
||||
GtkWindow *window;
|
||||
GSettings *settings;
|
||||
int old_width, old_height;
|
||||
int width, height;
|
||||
|
||||
settings = _gtk_file_chooser_get_settings_for_widget (GTK_WIDGET (dialog));
|
||||
|
||||
window = GTK_WINDOW (dialog);
|
||||
|
||||
gtk_window_get_size (window, &width, &height);
|
||||
|
||||
g_settings_get (settings, SETTINGS_KEY_WINDOW_SIZE, "(ii)", &old_width, &old_height);
|
||||
if (old_width != width || old_height != height)
|
||||
g_settings_set (settings, SETTINGS_KEY_WINDOW_SIZE, "(ii)", width, height);
|
||||
|
||||
g_settings_apply (settings);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_file_chooser_dialog_unmap (GtkWidget *widget)
|
||||
{
|
||||
GtkFileChooserDialog *dialog = GTK_FILE_CHOOSER_DIALOG (widget);
|
||||
|
||||
save_dialog_geometry (dialog);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_file_chooser_dialog_parent_class)->unmap (widget);
|
||||
}
|
||||
|
||||
@@ -593,6 +618,8 @@ gtk_file_chooser_dialog_size_allocate (GtkWidget *widget,
|
||||
width,
|
||||
height,
|
||||
baseline);
|
||||
if (gtk_widget_is_drawable (widget))
|
||||
save_dialog_geometry (GTK_FILE_CHOOSER_DIALOG (widget));
|
||||
}
|
||||
|
||||
/* We do a signal connection here rather than overriding the method in
|
||||
|
||||
+27
-15
@@ -2460,19 +2460,6 @@ location_changed_timeout_cb (gpointer user_data)
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
reset_location_timeout (GtkFileChooserWidget *impl)
|
||||
{
|
||||
GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
|
||||
|
||||
if (priv->location_changed_id > 0)
|
||||
g_source_remove (priv->location_changed_id);
|
||||
priv->location_changed_id = g_timeout_add (LOCATION_CHANGED_TIMEOUT,
|
||||
location_changed_timeout_cb,
|
||||
impl);
|
||||
g_source_set_name_by_id (priv->location_changed_id, "[gtk] location_changed_timeout_cb");
|
||||
}
|
||||
|
||||
static void
|
||||
location_entry_changed_cb (GtkEditable *editable,
|
||||
GtkFileChooserWidget *impl)
|
||||
@@ -2489,7 +2476,16 @@ location_entry_changed_cb (GtkEditable *editable,
|
||||
}
|
||||
|
||||
if (priv->action != GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
|
||||
reset_location_timeout (impl);
|
||||
{
|
||||
/* Reset location timeout */
|
||||
if (priv->location_changed_id > 0)
|
||||
g_source_remove (priv->location_changed_id);
|
||||
|
||||
priv->location_changed_id = g_timeout_add (LOCATION_CHANGED_TIMEOUT,
|
||||
location_changed_timeout_cb,
|
||||
impl);
|
||||
g_source_set_name_by_id (priv->location_changed_id, "[gtk] location_changed_timeout_cb");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3051,12 +3047,20 @@ static void
|
||||
operation_mode_set_browse (GtkFileChooserWidget *impl)
|
||||
{
|
||||
GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
|
||||
GtkRevealerTransitionType old_revealer_transition_type;
|
||||
|
||||
gtk_places_sidebar_set_location (GTK_PLACES_SIDEBAR (priv->places_sidebar), priv->current_folder);
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (priv->browse_files_stack), "list");
|
||||
location_mode_set (impl, LOCATION_MODE_PATH_BAR);
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (priv->browse_header_stack), "pathbar");
|
||||
|
||||
old_revealer_transition_type = gtk_revealer_get_transition_type (GTK_REVEALER (priv->browse_header_revealer));
|
||||
gtk_revealer_set_transition_type (GTK_REVEALER (priv->browse_header_revealer),
|
||||
GTK_REVEALER_TRANSITION_TYPE_NONE);
|
||||
gtk_revealer_set_reveal_child (GTK_REVEALER (priv->browse_header_revealer), TRUE);
|
||||
gtk_revealer_set_transition_type (GTK_REVEALER (priv->browse_header_revealer),
|
||||
old_revealer_transition_type);
|
||||
|
||||
gtk_widget_set_sensitive (priv->filter_combo, TRUE);
|
||||
g_object_notify (G_OBJECT (impl), "subtitle");
|
||||
}
|
||||
@@ -3090,10 +3094,19 @@ operation_mode_set_recent (GtkFileChooserWidget *impl)
|
||||
{
|
||||
GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
|
||||
GFile *file;
|
||||
GtkRevealerTransitionType old_revealer_transition_type;
|
||||
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (priv->browse_files_stack), "list");
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (priv->browse_header_stack), "pathbar");
|
||||
|
||||
/* Hide browse_header without a transition */
|
||||
old_revealer_transition_type = gtk_revealer_get_transition_type (GTK_REVEALER (priv->browse_header_revealer));
|
||||
gtk_revealer_set_transition_type (GTK_REVEALER (priv->browse_header_revealer),
|
||||
GTK_REVEALER_TRANSITION_TYPE_NONE);
|
||||
gtk_revealer_set_reveal_child (GTK_REVEALER (priv->browse_header_revealer), FALSE);
|
||||
gtk_revealer_set_transition_type (GTK_REVEALER (priv->browse_header_revealer),
|
||||
old_revealer_transition_type);
|
||||
|
||||
location_bar_update (impl);
|
||||
recent_start_loading (impl);
|
||||
file = g_file_new_for_uri ("recent:///");
|
||||
@@ -3584,7 +3597,6 @@ gtk_file_chooser_widget_unroot (GtkWidget *widget)
|
||||
|
||||
remove_settings_signal (impl, gtk_widget_get_display (widget));
|
||||
check_icon_theme (impl);
|
||||
emit_default_size_changed (impl);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_file_chooser_widget_parent_class)->unroot (widget);
|
||||
}
|
||||
|
||||
@@ -1543,6 +1543,16 @@ attribute_from_text (GtkBuilder *builder,
|
||||
if (gtk_builder_value_from_string_type (builder, G_TYPE_INT, value, &val, error))
|
||||
attribute = pango_attr_background_alpha_new ((guint16)g_value_get_int (&val));
|
||||
break;
|
||||
#if PANGO_VERSION_CHECK(1,44,0)
|
||||
case PANGO_ATTR_ALLOW_BREAKS:
|
||||
if (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, value, &val, error))
|
||||
attribute = pango_attr_allow_breaks_new (g_value_get_boolean (&val));
|
||||
break;
|
||||
case PANGO_ATTR_SHOW:
|
||||
if (gtk_builder_value_from_string_type (builder, PANGO_TYPE_SHOW_FLAGS, value, &val, error))
|
||||
attribute = pango_attr_show_new (g_value_get_flags (&val));
|
||||
break;
|
||||
#endif
|
||||
case PANGO_ATTR_INVALID:
|
||||
default:
|
||||
break;
|
||||
|
||||
+81
-1
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gtkmountoperationprivate.h"
|
||||
@@ -122,7 +123,10 @@ struct _GtkMountOperationPrivate {
|
||||
GtkWidget *username_entry;
|
||||
GtkWidget *domain_entry;
|
||||
GtkWidget *password_entry;
|
||||
GtkWidget *pim_entry;
|
||||
GtkWidget *anonymous_toggle;
|
||||
GtkWidget *tcrypt_hidden_toggle;
|
||||
GtkWidget *tcrypt_system_toggle;
|
||||
GList *user_widgets;
|
||||
|
||||
GAskPasswordFlags ask_flags;
|
||||
@@ -349,6 +353,27 @@ pw_dialog_got_response (GtkDialog *dialog,
|
||||
g_mount_operation_set_password (op, text);
|
||||
}
|
||||
|
||||
if (priv->pim_entry)
|
||||
{
|
||||
text = gtk_editable_get_text (GTK_EDITABLE (priv->pim_entry));
|
||||
if (text && strlen (text) > 0)
|
||||
{
|
||||
guint64 pim;
|
||||
gchar *end = NULL;
|
||||
|
||||
errno = 0;
|
||||
pim = g_ascii_strtoull (text, &end, 10);
|
||||
if (errno == 0 && pim <= G_MAXUINT && end != text)
|
||||
g_mount_operation_set_pim (op, (guint) pim);
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->tcrypt_hidden_toggle && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->tcrypt_hidden_toggle)))
|
||||
g_mount_operation_set_is_tcrypt_hidden_volume (op, TRUE);
|
||||
|
||||
if (priv->tcrypt_system_toggle && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->tcrypt_system_toggle)))
|
||||
g_mount_operation_set_is_tcrypt_system_volume (op, TRUE);
|
||||
|
||||
if (priv->ask_flags & G_ASK_PASSWORD_SAVING_SUPPORTED)
|
||||
g_mount_operation_set_password_save (op, priv->password_save);
|
||||
|
||||
@@ -376,6 +401,29 @@ entry_has_input (GtkWidget *entry_widget)
|
||||
return text != NULL && text[0] != '\0';
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pim_entry_is_valid (GtkWidget *entry_widget)
|
||||
{
|
||||
const char *text;
|
||||
gchar *end = NULL;
|
||||
guint64 pim;
|
||||
|
||||
if (entry_widget == NULL)
|
||||
return TRUE;
|
||||
|
||||
text = gtk_editable_get_text (GTK_EDITABLE (entry_widget));
|
||||
/* An empty PIM entry is OK */
|
||||
if (text == NULL || text[0] == '\0')
|
||||
return TRUE;
|
||||
|
||||
errno = 0;
|
||||
pim = g_ascii_strtoull (text, &end, 10);
|
||||
if (errno || pim > G_MAXUINT || end == text)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pw_dialog_input_is_valid (GtkMountOperation *operation)
|
||||
{
|
||||
@@ -389,7 +437,8 @@ pw_dialog_input_is_valid (GtkMountOperation *operation)
|
||||
* definitively needs a password.
|
||||
*/
|
||||
is_valid = entry_has_input (priv->username_entry) &&
|
||||
entry_has_input (priv->domain_entry);
|
||||
entry_has_input (priv->domain_entry) &&
|
||||
pim_entry_is_valid (priv->pim_entry);
|
||||
|
||||
return is_valid;
|
||||
}
|
||||
@@ -643,6 +692,31 @@ gtk_mount_operation_ask_password_do_gtk (GtkMountOperation *operation,
|
||||
priv->domain_entry = table_add_entry (operation, rows++, _("_Domain"),
|
||||
default_domain, operation);
|
||||
|
||||
priv->pim_entry = NULL;
|
||||
if (priv->ask_flags & G_ASK_PASSWORD_TCRYPT)
|
||||
{
|
||||
GtkWidget *volume_type_label;
|
||||
GtkWidget *volume_type_box;
|
||||
|
||||
volume_type_label = gtk_label_new (_("Volume type"));
|
||||
gtk_widget_set_halign (volume_type_label, GTK_ALIGN_END);
|
||||
gtk_widget_set_hexpand (volume_type_label, FALSE);
|
||||
gtk_grid_attach (GTK_GRID (grid), volume_type_label, 0, rows, 1, 1);
|
||||
priv->user_widgets = g_list_prepend (priv->user_widgets, volume_type_label);
|
||||
|
||||
volume_type_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
gtk_grid_attach (GTK_GRID (grid), volume_type_box, 1, rows++, 1, 1);
|
||||
priv->user_widgets = g_list_prepend (priv->user_widgets, volume_type_box);
|
||||
|
||||
priv->tcrypt_hidden_toggle = gtk_check_button_new_with_mnemonic (_("_Hidden"));
|
||||
gtk_container_add (GTK_CONTAINER (volume_type_box), priv->tcrypt_hidden_toggle);
|
||||
|
||||
priv->tcrypt_system_toggle = gtk_check_button_new_with_mnemonic (_("_Windows system"));
|
||||
gtk_container_add (GTK_CONTAINER (volume_type_box), priv->tcrypt_system_toggle);
|
||||
|
||||
priv->pim_entry = table_add_entry (operation, rows++, _("_PIM"), NULL, operation);
|
||||
}
|
||||
|
||||
priv->password_entry = NULL;
|
||||
if (priv->ask_flags & G_ASK_PASSWORD_NEED_PASSWORD)
|
||||
{
|
||||
@@ -759,6 +833,12 @@ call_password_proxy_cb (GObject *source,
|
||||
g_mount_operation_set_password (op, g_variant_get_string (value, NULL));
|
||||
else if (strcmp (key, "password_save") == 0)
|
||||
g_mount_operation_set_password_save (op, g_variant_get_uint32 (value));
|
||||
else if (strcmp (key, "hidden_volume") == 0)
|
||||
g_mount_operation_set_is_tcrypt_hidden_volume (op, g_variant_get_boolean (value));
|
||||
else if (strcmp (key, "system_volume") == 0)
|
||||
g_mount_operation_set_is_tcrypt_system_volume (op, g_variant_get_boolean (value));
|
||||
else if (strcmp (key, "pim") == 0)
|
||||
g_mount_operation_set_pim (op, g_variant_get_uint32 (value));
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
@@ -192,12 +192,6 @@ gtk_password_entry_dispose (GObject *object)
|
||||
G_OBJECT_CLASS (gtk_password_entry_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_password_entry_finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (gtk_password_entry_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_password_entry_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
@@ -380,7 +374,6 @@ gtk_password_entry_class_init (GtkPasswordEntryClass *klass)
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = gtk_password_entry_dispose;
|
||||
object_class->finalize = gtk_password_entry_finalize;
|
||||
object_class->get_property = gtk_password_entry_get_property;
|
||||
object_class->set_property = gtk_password_entry_set_property;
|
||||
|
||||
@@ -477,6 +470,8 @@ gtk_password_entry_set_show_peek_icon (GtkPasswordEntry *entry,
|
||||
|
||||
g_return_if_fail (GTK_IS_PASSWORD_ENTRY (entry));
|
||||
|
||||
show_peek_icon = !!show_peek_icon;
|
||||
|
||||
if (show_peek_icon == (priv->peek_icon != NULL))
|
||||
return;
|
||||
|
||||
|
||||
+15
-3
@@ -1999,10 +1999,22 @@ listbox_filter_func (GtkListBoxRow *row,
|
||||
NULL);
|
||||
|
||||
if (name)
|
||||
retval |= strstr (name, priv->search_query) != NULL;
|
||||
{
|
||||
char *lowercase_name = g_utf8_strdown (name, -1);
|
||||
|
||||
retval |= strstr (lowercase_name, priv->search_query) != NULL;
|
||||
|
||||
g_free (lowercase_name);
|
||||
}
|
||||
|
||||
if (path)
|
||||
retval |= strstr (path, priv->search_query) != NULL;
|
||||
{
|
||||
char *lowercase_path = g_utf8_strdown (path, -1);
|
||||
|
||||
retval |= strstr (lowercase_path, priv->search_query) != NULL;
|
||||
|
||||
g_free (lowercase_path);
|
||||
}
|
||||
|
||||
g_free (name);
|
||||
g_free (path);
|
||||
@@ -2459,7 +2471,7 @@ gtk_places_view_set_search_query (GtkPlacesView *view,
|
||||
if (g_strcmp0 (priv->search_query, query_text) != 0)
|
||||
{
|
||||
g_clear_pointer (&priv->search_query, g_free);
|
||||
priv->search_query = g_strdup (query_text);
|
||||
priv->search_query = g_utf8_strdown (query_text, -1);
|
||||
|
||||
gtk_list_box_invalidate_filter (GTK_LIST_BOX (priv->listbox));
|
||||
gtk_list_box_invalidate_headers (GTK_LIST_BOX (priv->listbox));
|
||||
|
||||
+2
-6
@@ -1091,8 +1091,7 @@ gtk_popover_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation child_alloc;
|
||||
int tail_height = priv->has_arrow ? TAIL_HEIGHT : 0;
|
||||
|
||||
if (priv->surface)
|
||||
gtk_popover_move_resize (popover);
|
||||
gtk_popover_move_resize (popover);
|
||||
|
||||
switch (priv->final_position)
|
||||
{
|
||||
@@ -1414,10 +1413,7 @@ size_changed (GtkWidget *widget,
|
||||
int baseline,
|
||||
GtkPopover *popover)
|
||||
{
|
||||
GtkPopoverPrivate *priv = gtk_popover_get_instance_private (popover);
|
||||
|
||||
if (priv->surface)
|
||||
gtk_popover_move_resize (popover);
|
||||
gtk_popover_move_resize (popover);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/* gtkpropertyanimation.c: An animation controlling a single property
|
||||
*
|
||||
* Copyright 2019 GNOME Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "gtkpropertyanimation.h"
|
||||
|
||||
#include "gtktransitionprivate.h"
|
||||
|
||||
enum
|
||||
{
|
||||
INITIAL,
|
||||
FINAL,
|
||||
N_STATES
|
||||
};
|
||||
|
||||
struct _GtkPropertyAnimation
|
||||
{
|
||||
GtkTransition parent_instance;
|
||||
|
||||
GValue interval[N_STATES];
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GtkPropertyAnimation, gtk_property_animation, GTK_TYPE_ANIMATION)
|
||||
|
||||
static void
|
||||
gtk_property_animation_class_init (GtkPropertyAnimationClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_property_animation_init (GtkPropertyAnimation *self)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/* gtkpropertyanimation.h: An animation controlling a single object property
|
||||
*
|
||||
* Copyright 2019 GNOME Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtkanimation.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* GtkPropertyAnimation:
|
||||
*
|
||||
* A animation that operates on a single property of a #GObject.
|
||||
*/
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
G_DECLARE_FINAL_TYPE (GtkPropertyAnimation, gtk_property_animation, GTK, PROPERTY_ANIMATION, GtkAnimation)
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkAnimation * gtk_property_animation_new (const char *property_name);
|
||||
|
||||
/* Interval */
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_property_animation_set_from (GtkPropertyAnimation *animation,
|
||||
...);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_property_animation_set_from_value (GtkPropertyAnimation *animation,
|
||||
const GValue *value);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_property_animation_set_to (GtkPropertyAnimation *animation,
|
||||
...);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_property_animation_set_to_value (GtkPropertyAnimation *animation,
|
||||
const GValue *value);
|
||||
|
||||
G_END_DECLS
|
||||
+18
-1
@@ -50,18 +50,24 @@ gtk_root_default_get_display (GtkRoot *self)
|
||||
return gdk_display_get_default ();
|
||||
}
|
||||
|
||||
|
||||
static GtkConstraintSolver *
|
||||
gtk_root_default_get_constraint_solver (GtkRoot *self)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GtkAnimationManager *
|
||||
gtk_root_default_get_animation_manager (GtkRoot *self)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_root_default_init (GtkRootInterface *iface)
|
||||
{
|
||||
iface->get_display = gtk_root_default_get_display;
|
||||
iface->get_constraint_solver = gtk_root_default_get_constraint_solver;
|
||||
iface->get_animation_manager = gtk_root_default_get_animation_manager;
|
||||
|
||||
g_object_interface_install_property (iface,
|
||||
g_param_spec_object ("focus-widget",
|
||||
@@ -101,6 +107,17 @@ gtk_root_get_constraint_solver (GtkRoot *self)
|
||||
return iface->get_constraint_solver (self);
|
||||
}
|
||||
|
||||
GtkAnimationManager *
|
||||
gtk_root_get_animation_manager (GtkRoot *self)
|
||||
{
|
||||
GtkRootInterface *iface;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_ROOT (self), NULL);
|
||||
|
||||
iface = GTK_ROOT_GET_IFACE (self);
|
||||
return iface->get_animation_manager (self);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_root_set_focus:
|
||||
* @self: a #GtkRoot
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
|
||||
#include "gtkroot.h"
|
||||
|
||||
#include "gtkanimationmanagerprivate.h"
|
||||
#include "gtkconstraintsolverprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
/*< private >
|
||||
* GtkRootIface:
|
||||
*
|
||||
* The list of functions that must be implemented for the #GtkRoot interface.
|
||||
@@ -21,9 +22,11 @@ struct _GtkRootInterface
|
||||
GdkDisplay * (* get_display) (GtkRoot *self);
|
||||
|
||||
GtkConstraintSolver * (* get_constraint_solver) (GtkRoot *self);
|
||||
GtkAnimationManager * (* get_animation_manager) (GtkRoot *self);
|
||||
};
|
||||
|
||||
GtkConstraintSolver * gtk_root_get_constraint_solver (GtkRoot *self);
|
||||
GtkAnimationManager * gtk_root_get_animation_manager (GtkRoot *self);
|
||||
|
||||
enum {
|
||||
GTK_ROOT_PROP_FOCUS_WIDGET,
|
||||
|
||||
+1
-1
@@ -2062,7 +2062,7 @@ settings_update_font_options (GtkSettings *settings)
|
||||
|
||||
priv->font_options = cairo_font_options_create ();
|
||||
|
||||
cairo_font_options_set_hint_metrics (priv->font_options, CAIRO_HINT_METRICS_ON);
|
||||
cairo_font_options_set_hint_metrics (priv->font_options, CAIRO_HINT_METRICS_OFF);
|
||||
|
||||
hint_style = CAIRO_HINT_STYLE_DEFAULT;
|
||||
if (hinting == 0)
|
||||
|
||||
+119
-87
@@ -195,8 +195,9 @@ struct _GtkTextPrivate
|
||||
|
||||
gunichar invisible_char;
|
||||
|
||||
guint blink_time; /* time in msec the cursor has blinked since last user event */
|
||||
guint blink_timeout;
|
||||
guint64 blink_start_time;
|
||||
guint blink_tick;
|
||||
float cursor_alpha;
|
||||
|
||||
guint16 preedit_length; /* length of preedit string, in bytes */
|
||||
guint16 preedit_cursor; /* offset of cursor within preedit string, in chars */
|
||||
@@ -212,7 +213,6 @@ struct _GtkTextPrivate
|
||||
guint activates_default : 1;
|
||||
guint cache_includes_preedit : 1;
|
||||
guint change_count : 8;
|
||||
guint cursor_visible : 1;
|
||||
guint editing_canceled : 1; /* Only used by GtkCellRendererText */
|
||||
guint in_click : 1; /* Flag so we don't select all when clicking in entry to focus in */
|
||||
guint invisible_char_set : 1;
|
||||
@@ -1765,10 +1765,10 @@ gtk_text_destroy (GtkWidget *widget)
|
||||
gtk_text_reset_im_context (self);
|
||||
gtk_text_reset_layout (self);
|
||||
|
||||
if (priv->blink_timeout)
|
||||
if (priv->blink_tick)
|
||||
{
|
||||
g_source_remove (priv->blink_timeout);
|
||||
priv->blink_timeout = 0;
|
||||
gtk_widget_remove_tick_callback (widget, priv->blink_tick);
|
||||
priv->blink_tick = 0;
|
||||
}
|
||||
|
||||
if (priv->magnifier)
|
||||
@@ -1825,9 +1825,6 @@ gtk_text_finalize (GObject *object)
|
||||
|
||||
g_clear_pointer (&priv->placeholder, gtk_widget_unparent);
|
||||
|
||||
if (priv->blink_timeout)
|
||||
g_source_remove (priv->blink_timeout);
|
||||
|
||||
if (priv->tabs)
|
||||
pango_tab_array_free (priv->tabs);
|
||||
|
||||
@@ -2193,9 +2190,6 @@ gtk_text_size_allocate (GtkWidget *widget,
|
||||
-1);
|
||||
}
|
||||
|
||||
/* Do this here instead of gtk_text_size_allocate() so it works
|
||||
* inside spinbuttons, which don't chain up.
|
||||
*/
|
||||
if (gtk_widget_get_realized (widget))
|
||||
gtk_text_recompute (self);
|
||||
|
||||
@@ -2267,8 +2261,12 @@ gtk_text_snapshot (GtkWidget *widget,
|
||||
/* When no text is being displayed at all, don't show the cursor */
|
||||
if (gtk_text_get_display_mode (self) != DISPLAY_BLANK &&
|
||||
gtk_widget_has_focus (widget) &&
|
||||
priv->selection_bound == priv->current_pos && priv->cursor_visible)
|
||||
gtk_text_draw_cursor (self, snapshot, CURSOR_STANDARD);
|
||||
priv->selection_bound == priv->current_pos)
|
||||
{
|
||||
gtk_snapshot_push_opacity (snapshot, priv->cursor_alpha);
|
||||
gtk_text_draw_cursor (self, snapshot, CURSOR_STANDARD);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
|
||||
gtk_text_draw_undershoot (self, snapshot);
|
||||
}
|
||||
@@ -3261,10 +3259,21 @@ static void
|
||||
gtk_text_style_updated (GtkWidget *widget)
|
||||
{
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
GtkStyleContext *context;
|
||||
GtkCssStyleChange *change = NULL;
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
change = gtk_style_context_get_change (context);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_text_parent_class)->style_updated (widget);
|
||||
|
||||
gtk_text_update_cached_style_values (self);
|
||||
|
||||
if (change == NULL ||
|
||||
gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_TEXT |
|
||||
GTK_CSS_AFFECTS_BACKGROUND |
|
||||
GTK_CSS_AFFECTS_CONTENT))
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -6293,47 +6302,85 @@ get_cursor_blink_timeout (GtkText *self)
|
||||
return timeout;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
guint64 start;
|
||||
guint64 end;
|
||||
} BlinkData;
|
||||
|
||||
static gboolean blink_cb (GtkWidget *widget,
|
||||
GdkFrameClock *clock,
|
||||
gpointer user_data);
|
||||
|
||||
static void
|
||||
show_cursor (GtkText *self)
|
||||
add_blink_timeout (GtkText *self,
|
||||
gboolean delay)
|
||||
{
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
GtkWidget *widget;
|
||||
BlinkData *data;
|
||||
int blink_time;
|
||||
|
||||
if (!priv->cursor_visible)
|
||||
{
|
||||
priv->cursor_visible = TRUE;
|
||||
priv->blink_start_time = g_get_monotonic_time ();
|
||||
priv->cursor_alpha = 1.0;
|
||||
|
||||
widget = GTK_WIDGET (self);
|
||||
if (gtk_widget_has_focus (widget) && priv->selection_bound == priv->current_pos)
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
blink_time = get_cursor_time (self);
|
||||
|
||||
data = g_new (BlinkData, 1);
|
||||
data->start = priv->blink_start_time;
|
||||
if (delay)
|
||||
data->start += blink_time * 1000 / 2;
|
||||
data->end = data->start + blink_time * 1000;
|
||||
|
||||
priv->blink_tick = gtk_widget_add_tick_callback (GTK_WIDGET (self),
|
||||
blink_cb,
|
||||
data,
|
||||
g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
hide_cursor (GtkText *self)
|
||||
remove_blink_timeout (GtkText *self)
|
||||
{
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
GtkWidget *widget;
|
||||
|
||||
if (priv->cursor_visible)
|
||||
if (priv->blink_tick)
|
||||
{
|
||||
priv->cursor_visible = FALSE;
|
||||
|
||||
widget = GTK_WIDGET (self);
|
||||
if (gtk_widget_has_focus (widget) && priv->selection_bound == priv->current_pos)
|
||||
gtk_widget_queue_draw (widget);
|
||||
gtk_widget_remove_tick_callback (GTK_WIDGET (self), priv->blink_tick);
|
||||
priv->blink_tick = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Blink!
|
||||
*/
|
||||
static int
|
||||
blink_cb (gpointer data)
|
||||
|
||||
static float
|
||||
blink_alpha (float phase)
|
||||
{
|
||||
GtkText *self = data;
|
||||
/* keep it simple, and split the blink cycle evenly
|
||||
* into visible, fading out, invisible, fading in
|
||||
*/
|
||||
if (phase < 0.25)
|
||||
return 1;
|
||||
else if (phase < 0.5)
|
||||
return 1 - 4 * (phase - 0.25);
|
||||
else if (phase < 0.75)
|
||||
return 0;
|
||||
else
|
||||
return 4 * (phase - 0.75);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
blink_cb (GtkWidget *widget,
|
||||
GdkFrameClock *clock,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
BlinkData *data = user_data;
|
||||
int blink_timeout;
|
||||
int blink_time;
|
||||
guint64 now;
|
||||
float phase;
|
||||
float alpha;
|
||||
|
||||
if (!gtk_widget_has_focus (GTK_WIDGET (self)))
|
||||
{
|
||||
@@ -6342,39 +6389,43 @@ blink_cb (gpointer data)
|
||||
"GDK_EVENT_PROPAGATE so the self gets the event as well");
|
||||
|
||||
gtk_text_check_cursor_blink (self);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
g_assert (priv->selection_bound == priv->current_pos);
|
||||
|
||||
blink_timeout = get_cursor_blink_timeout (self);
|
||||
blink_time = get_cursor_time (self);
|
||||
|
||||
now = g_get_monotonic_time ();
|
||||
|
||||
if (now > priv->blink_start_time + blink_timeout * 1000000)
|
||||
{
|
||||
/* we've blinked enough without the user doing anything, stop blinking */
|
||||
priv->cursor_alpha = 1.0;
|
||||
remove_blink_timeout (self);
|
||||
gtk_widget_queue_draw (widget);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
g_assert (priv->selection_bound == priv->current_pos);
|
||||
|
||||
blink_timeout = get_cursor_blink_timeout (self);
|
||||
if (priv->blink_time > 1000 * blink_timeout &&
|
||||
blink_timeout < G_MAXINT/1000)
|
||||
|
||||
phase = (now - data->start) / (float) (data->end - data->start);
|
||||
|
||||
if (now >= data->end)
|
||||
{
|
||||
/* we've blinked enough without the user doing anything, stop blinking */
|
||||
show_cursor (self);
|
||||
priv->blink_timeout = 0;
|
||||
}
|
||||
else if (priv->cursor_visible)
|
||||
{
|
||||
hide_cursor (self);
|
||||
priv->blink_timeout = g_timeout_add (get_cursor_time (self) * CURSOR_OFF_MULTIPLIER / CURSOR_DIVIDER,
|
||||
blink_cb,
|
||||
self);
|
||||
g_source_set_name_by_id (priv->blink_timeout, "[gtk] blink_cb");
|
||||
}
|
||||
else
|
||||
{
|
||||
show_cursor (self);
|
||||
priv->blink_time += get_cursor_time (self);
|
||||
priv->blink_timeout = g_timeout_add (get_cursor_time (self) * CURSOR_ON_MULTIPLIER / CURSOR_DIVIDER,
|
||||
blink_cb,
|
||||
self);
|
||||
g_source_set_name_by_id (priv->blink_timeout, "[gtk] blink_cb");
|
||||
data->start = data->end;
|
||||
data->end = data->start + blink_time * 1000;
|
||||
}
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
alpha = blink_alpha (phase);
|
||||
|
||||
if (priv->cursor_alpha != alpha)
|
||||
{
|
||||
priv->cursor_alpha = alpha;
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -6384,42 +6435,23 @@ gtk_text_check_cursor_blink (GtkText *self)
|
||||
|
||||
if (cursor_blinks (self))
|
||||
{
|
||||
if (!priv->blink_timeout)
|
||||
{
|
||||
show_cursor (self);
|
||||
priv->blink_timeout = g_timeout_add (get_cursor_time (self) * CURSOR_ON_MULTIPLIER / CURSOR_DIVIDER,
|
||||
blink_cb,
|
||||
self);
|
||||
g_source_set_name_by_id (priv->blink_timeout, "[gtk] blink_cb");
|
||||
}
|
||||
if (!priv->blink_tick)
|
||||
add_blink_timeout (self, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (priv->blink_timeout)
|
||||
{
|
||||
g_source_remove (priv->blink_timeout);
|
||||
priv->blink_timeout = 0;
|
||||
}
|
||||
|
||||
priv->cursor_visible = TRUE;
|
||||
if (priv->blink_tick)
|
||||
remove_blink_timeout (self);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_pend_cursor_blink (GtkText *self)
|
||||
{
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
|
||||
if (cursor_blinks (self))
|
||||
{
|
||||
if (priv->blink_timeout != 0)
|
||||
g_source_remove (priv->blink_timeout);
|
||||
|
||||
priv->blink_timeout = g_timeout_add (get_cursor_time (self) * CURSOR_PEND_MULTIPLIER / CURSOR_DIVIDER,
|
||||
blink_cb,
|
||||
self);
|
||||
g_source_set_name_by_id (priv->blink_timeout, "[gtk] blink_cb");
|
||||
show_cursor (self);
|
||||
remove_blink_timeout (self);
|
||||
add_blink_timeout (self, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6428,7 +6460,7 @@ gtk_text_reset_blink_time (GtkText *self)
|
||||
{
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
|
||||
priv->blink_time = 0;
|
||||
priv->blink_start_time = g_get_monotonic_time ();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,932 +0,0 @@
|
||||
/* gtktextdisplay.c - display layed-out text
|
||||
*
|
||||
* Copyright (c) 1992-1994 The Regents of the University of California.
|
||||
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
|
||||
* Copyright (c) 2000 Red Hat, Inc.
|
||||
* Tk->Gtk port by Havoc Pennington
|
||||
*
|
||||
* This file can be used under your choice of two licenses, the LGPL
|
||||
* and the original Tk license.
|
||||
*
|
||||
* LGPL:
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.Free
|
||||
*
|
||||
* Original Tk license:
|
||||
*
|
||||
* This software is copyrighted by the Regents of the University of
|
||||
* California, Sun Microsystems, Inc., and other parties. The
|
||||
* following terms apply to all files associated with the software
|
||||
* unless explicitly disclaimed in individual files.
|
||||
*
|
||||
* The authors hereby grant permission to use, copy, modify,
|
||||
* distribute, and license this software and its documentation for any
|
||||
* purpose, provided that existing copyright notices are retained in
|
||||
* all copies and that this notice is included verbatim in any
|
||||
* distributions. No written agreement, license, or royalty fee is
|
||||
* required for any of the authorized uses. Modifications to this
|
||||
* software may be copyrighted by their authors and need not follow
|
||||
* the licensing terms described here, provided that the new terms are
|
||||
* clearly indicated on the first page of each file where they apply.
|
||||
*
|
||||
* IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY
|
||||
* PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
|
||||
* DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION,
|
||||
* OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
|
||||
* NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
|
||||
* AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
|
||||
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
* GOVERNMENT USE: If you are acquiring this software on behalf of the
|
||||
* U.S. government, the Government shall have only "Restricted Rights"
|
||||
* in the software and related documentation as defined in the Federal
|
||||
* Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
|
||||
* are acquiring the software on behalf of the Department of Defense,
|
||||
* the software shall be classified as "Commercial Computer Software"
|
||||
* and the Government shall have only "Restricted Rights" as defined
|
||||
* in Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the
|
||||
* foregoing, the authors grant the U.S. Government and others acting
|
||||
* in its behalf permission to use and distribute the software in
|
||||
* accordance with the terms specified in this license.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "gtktextdisplayprivate.h"
|
||||
#include "gtktextviewprivate.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkstylecontextprivate.h"
|
||||
#include "gtkintl.h"
|
||||
#include <gdk/gdktextureprivate.h>
|
||||
|
||||
#define GTK_TYPE_TEXT_RENDERER (_gtk_text_renderer_get_type())
|
||||
#define GTK_TEXT_RENDERER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GTK_TYPE_TEXT_RENDERER, GtkTextRenderer))
|
||||
#define GTK_IS_TEXT_RENDERER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GTK_TYPE_TEXT_RENDERER))
|
||||
#define GTK_TEXT_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_TEXT_RENDERER, GtkTextRendererClass))
|
||||
#define GTK_IS_TEXT_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_TEXT_RENDERER))
|
||||
#define GTK_TEXT_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_TEXT_RENDERER, GtkTextRendererClass))
|
||||
|
||||
typedef struct _GtkTextRenderer GtkTextRenderer;
|
||||
typedef struct _GtkTextRendererClass GtkTextRendererClass;
|
||||
|
||||
enum {
|
||||
NORMAL,
|
||||
SELECTED,
|
||||
CURSOR
|
||||
};
|
||||
|
||||
struct _GtkTextRenderer
|
||||
{
|
||||
PangoRenderer parent_instance;
|
||||
|
||||
GtkWidget *widget;
|
||||
cairo_t *cr;
|
||||
|
||||
GdkRGBA *error_color; /* Error underline color for this widget */
|
||||
GList *widgets; /* widgets encountered when drawing */
|
||||
|
||||
guint state : 2;
|
||||
};
|
||||
|
||||
struct _GtkTextRendererClass
|
||||
{
|
||||
PangoRendererClass parent_class;
|
||||
};
|
||||
|
||||
GType _gtk_text_renderer_get_type (void);
|
||||
|
||||
G_DEFINE_TYPE (GtkTextRenderer, _gtk_text_renderer, PANGO_TYPE_RENDERER)
|
||||
|
||||
static void
|
||||
text_renderer_set_rgba (GtkTextRenderer *text_renderer,
|
||||
PangoRenderPart part,
|
||||
const GdkRGBA *rgba)
|
||||
{
|
||||
PangoRenderer *renderer = PANGO_RENDERER (text_renderer);
|
||||
PangoColor color = { 0, };
|
||||
guint16 alpha;
|
||||
|
||||
if (rgba)
|
||||
{
|
||||
color.red = (guint16)(rgba->red * 65535);
|
||||
color.green = (guint16)(rgba->green * 65535);
|
||||
color.blue = (guint16)(rgba->blue * 65535);
|
||||
alpha = (guint16)(rgba->alpha * 65535);
|
||||
pango_renderer_set_color (renderer, part, &color);
|
||||
pango_renderer_set_alpha (renderer, part, alpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
pango_renderer_set_color (renderer, part, NULL);
|
||||
pango_renderer_set_alpha (renderer, part, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static GtkTextAppearance *
|
||||
get_item_appearance (PangoItem *item)
|
||||
{
|
||||
GSList *tmp_list = item->analysis.extra_attrs;
|
||||
|
||||
while (tmp_list)
|
||||
{
|
||||
PangoAttribute *attr = tmp_list->data;
|
||||
|
||||
if (attr->klass->type == gtk_text_attr_appearance_type)
|
||||
return &((GtkTextAttrAppearance *)attr)->appearance;
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_renderer_prepare_run (PangoRenderer *renderer,
|
||||
PangoLayoutRun *run)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
GtkTextRenderer *text_renderer = GTK_TEXT_RENDERER (renderer);
|
||||
GdkRGBA *bg_rgba = NULL;
|
||||
GdkRGBA *fg_rgba = NULL;
|
||||
GtkTextAppearance *appearance;
|
||||
|
||||
PANGO_RENDERER_CLASS (_gtk_text_renderer_parent_class)->prepare_run (renderer, run);
|
||||
|
||||
appearance = get_item_appearance (run->item);
|
||||
g_assert (appearance != NULL);
|
||||
|
||||
context = gtk_widget_get_style_context (text_renderer->widget);
|
||||
|
||||
if (appearance->draw_bg && text_renderer->state == NORMAL)
|
||||
bg_rgba = appearance->bg_rgba;
|
||||
else
|
||||
bg_rgba = NULL;
|
||||
|
||||
text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_BACKGROUND, bg_rgba);
|
||||
|
||||
if (text_renderer->state == SELECTED)
|
||||
{
|
||||
GtkCssNode *selection_node;
|
||||
|
||||
selection_node = gtk_text_view_get_selection_node ((GtkTextView *)text_renderer->widget);
|
||||
gtk_style_context_save_to_node (context, selection_node);
|
||||
|
||||
gtk_style_context_get (context,
|
||||
"color", &fg_rgba,
|
||||
NULL);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
}
|
||||
else if (text_renderer->state == CURSOR && gtk_widget_has_focus (text_renderer->widget))
|
||||
{
|
||||
gtk_style_context_get (context,
|
||||
"background-color", &fg_rgba,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
fg_rgba = appearance->fg_rgba;
|
||||
|
||||
text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_FOREGROUND, fg_rgba);
|
||||
|
||||
if (appearance->strikethrough_rgba)
|
||||
text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_STRIKETHROUGH, appearance->strikethrough_rgba);
|
||||
else
|
||||
text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_STRIKETHROUGH, fg_rgba);
|
||||
|
||||
if (appearance->underline_rgba)
|
||||
text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_UNDERLINE, appearance->underline_rgba);
|
||||
else if (appearance->underline == PANGO_UNDERLINE_ERROR)
|
||||
{
|
||||
if (!text_renderer->error_color)
|
||||
{
|
||||
static const GdkRGBA red = { 1, 0, 0, 1 };
|
||||
text_renderer->error_color = gdk_rgba_copy (&red);
|
||||
}
|
||||
|
||||
text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_UNDERLINE, text_renderer->error_color);
|
||||
}
|
||||
else
|
||||
text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_UNDERLINE, fg_rgba);
|
||||
|
||||
if (fg_rgba != appearance->fg_rgba)
|
||||
gdk_rgba_free (fg_rgba);
|
||||
}
|
||||
|
||||
static void
|
||||
set_color (GtkTextRenderer *text_renderer,
|
||||
PangoRenderPart part)
|
||||
{
|
||||
PangoColor *color;
|
||||
GdkRGBA rgba;
|
||||
guint16 alpha;
|
||||
|
||||
cairo_save (text_renderer->cr);
|
||||
|
||||
color = pango_renderer_get_color (PANGO_RENDERER (text_renderer), part);
|
||||
alpha = pango_renderer_get_alpha (PANGO_RENDERER (text_renderer), part);
|
||||
if (color)
|
||||
{
|
||||
rgba.red = color->red / 65535.;
|
||||
rgba.green = color->green / 65535.;
|
||||
rgba.blue = color->blue / 65535.;
|
||||
rgba.alpha = alpha / 65535.;
|
||||
gdk_cairo_set_source_rgba (text_renderer->cr, &rgba);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
unset_color (GtkTextRenderer *text_renderer)
|
||||
{
|
||||
cairo_restore (text_renderer->cr);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_renderer_draw_glyphs (PangoRenderer *renderer,
|
||||
PangoFont *font,
|
||||
PangoGlyphString *glyphs,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
GtkTextRenderer *text_renderer = GTK_TEXT_RENDERER (renderer);
|
||||
|
||||
set_color (text_renderer, PANGO_RENDER_PART_FOREGROUND);
|
||||
|
||||
cairo_move_to (text_renderer->cr, (double)x / PANGO_SCALE, (double)y / PANGO_SCALE);
|
||||
pango_cairo_show_glyph_string (text_renderer->cr, font, glyphs);
|
||||
|
||||
unset_color (text_renderer);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_renderer_draw_glyph_item (PangoRenderer *renderer,
|
||||
const char *text,
|
||||
PangoGlyphItem *glyph_item,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
GtkTextRenderer *text_renderer = GTK_TEXT_RENDERER (renderer);
|
||||
|
||||
set_color (text_renderer, PANGO_RENDER_PART_FOREGROUND);
|
||||
|
||||
cairo_move_to (text_renderer->cr, (double)x / PANGO_SCALE, (double)y / PANGO_SCALE);
|
||||
pango_cairo_show_glyph_item (text_renderer->cr, text, glyph_item);
|
||||
|
||||
unset_color (text_renderer);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_renderer_draw_rectangle (PangoRenderer *renderer,
|
||||
PangoRenderPart part,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
GtkTextRenderer *text_renderer = GTK_TEXT_RENDERER (renderer);
|
||||
|
||||
set_color (text_renderer, part);
|
||||
|
||||
cairo_rectangle (text_renderer->cr,
|
||||
(double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
|
||||
(double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
|
||||
cairo_fill (text_renderer->cr);
|
||||
|
||||
unset_color (text_renderer);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_renderer_draw_trapezoid (PangoRenderer *renderer,
|
||||
PangoRenderPart part,
|
||||
double y1_,
|
||||
double x11,
|
||||
double x21,
|
||||
double y2,
|
||||
double x12,
|
||||
double x22)
|
||||
{
|
||||
GtkTextRenderer *text_renderer = GTK_TEXT_RENDERER (renderer);
|
||||
cairo_t *cr;
|
||||
cairo_matrix_t matrix;
|
||||
|
||||
set_color (text_renderer, part);
|
||||
|
||||
cr = text_renderer->cr;
|
||||
|
||||
cairo_get_matrix (cr, &matrix);
|
||||
matrix.xx = matrix.yy = 1.0;
|
||||
matrix.xy = matrix.yx = 0.0;
|
||||
cairo_set_matrix (cr, &matrix);
|
||||
|
||||
cairo_move_to (cr, x11, y1_);
|
||||
cairo_line_to (cr, x21, y1_);
|
||||
cairo_line_to (cr, x22, y2);
|
||||
cairo_line_to (cr, x12, y2);
|
||||
cairo_close_path (cr);
|
||||
|
||||
cairo_fill (cr);
|
||||
|
||||
unset_color (text_renderer);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_renderer_draw_error_underline (PangoRenderer *renderer,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
GtkTextRenderer *text_renderer = GTK_TEXT_RENDERER (renderer);
|
||||
|
||||
set_color (text_renderer, PANGO_RENDER_PART_UNDERLINE);
|
||||
|
||||
pango_cairo_show_error_underline (text_renderer->cr,
|
||||
(double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
|
||||
(double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
|
||||
|
||||
unset_color (text_renderer);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_renderer_draw_shape (PangoRenderer *renderer,
|
||||
PangoAttrShape *attr,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
GtkTextRenderer *text_renderer = GTK_TEXT_RENDERER (renderer);
|
||||
|
||||
if (attr->data == NULL)
|
||||
{
|
||||
/* This happens if we have an empty widget anchor. Draw
|
||||
* something empty-looking.
|
||||
*/
|
||||
GdkRectangle shape_rect;
|
||||
cairo_t *cr;
|
||||
|
||||
shape_rect.x = PANGO_PIXELS (x);
|
||||
shape_rect.y = PANGO_PIXELS (y + attr->logical_rect.y);
|
||||
shape_rect.width = PANGO_PIXELS (x + attr->logical_rect.width) - shape_rect.x;
|
||||
shape_rect.height = PANGO_PIXELS (y + attr->logical_rect.y + attr->logical_rect.height) - shape_rect.y;
|
||||
|
||||
set_color (text_renderer, PANGO_RENDER_PART_FOREGROUND);
|
||||
|
||||
cr = text_renderer->cr;
|
||||
|
||||
cairo_set_line_width (cr, 1.0);
|
||||
|
||||
cairo_rectangle (cr,
|
||||
shape_rect.x + 0.5, shape_rect.y + 0.5,
|
||||
shape_rect.width - 1, shape_rect.height - 1);
|
||||
cairo_move_to (cr, shape_rect.x + 0.5, shape_rect.y + 0.5);
|
||||
cairo_line_to (cr,
|
||||
shape_rect.x + shape_rect.width - 0.5,
|
||||
shape_rect.y + shape_rect.height - 0.5);
|
||||
cairo_move_to (cr, shape_rect.x + 0.5,
|
||||
shape_rect.y + shape_rect.height - 0.5);
|
||||
cairo_line_to (cr, shape_rect.x + shape_rect.width - 0.5,
|
||||
shape_rect.y + 0.5);
|
||||
|
||||
cairo_stroke (cr);
|
||||
|
||||
unset_color (text_renderer);
|
||||
}
|
||||
else if (GDK_IS_TEXTURE (attr->data))
|
||||
{
|
||||
cairo_t *cr = text_renderer->cr;
|
||||
GdkTexture *texture = GDK_TEXTURE (attr->data);
|
||||
cairo_surface_t *surface;
|
||||
|
||||
surface = gdk_texture_download_surface (texture);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_set_source_surface (cr, surface,
|
||||
PANGO_PIXELS (x),
|
||||
PANGO_PIXELS (y) - gdk_texture_get_height (texture));
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
else if (GTK_IS_WIDGET (attr->data))
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = GTK_WIDGET (attr->data);
|
||||
|
||||
text_renderer->widgets = g_list_prepend (text_renderer->widgets,
|
||||
g_object_ref (widget));
|
||||
}
|
||||
else
|
||||
g_assert_not_reached (); /* not a texture or widget */
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_renderer_finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (_gtk_text_renderer_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_text_renderer_init (GtkTextRenderer *renderer)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_text_renderer_class_init (GtkTextRendererClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
PangoRendererClass *renderer_class = PANGO_RENDERER_CLASS (klass);
|
||||
|
||||
renderer_class->prepare_run = gtk_text_renderer_prepare_run;
|
||||
renderer_class->draw_glyphs = gtk_text_renderer_draw_glyphs;
|
||||
renderer_class->draw_glyph_item = gtk_text_renderer_draw_glyph_item;
|
||||
renderer_class->draw_rectangle = gtk_text_renderer_draw_rectangle;
|
||||
renderer_class->draw_trapezoid = gtk_text_renderer_draw_trapezoid;
|
||||
renderer_class->draw_error_underline = gtk_text_renderer_draw_error_underline;
|
||||
renderer_class->draw_shape = gtk_text_renderer_draw_shape;
|
||||
|
||||
object_class->finalize = gtk_text_renderer_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
text_renderer_set_state (GtkTextRenderer *text_renderer,
|
||||
int state)
|
||||
{
|
||||
text_renderer->state = state;
|
||||
}
|
||||
|
||||
static void
|
||||
text_renderer_begin (GtkTextRenderer *text_renderer,
|
||||
GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
GdkRGBA color;
|
||||
GtkCssNode *text_node;
|
||||
|
||||
text_renderer->widget = widget;
|
||||
text_renderer->cr = cr;
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
|
||||
text_node = gtk_text_view_get_text_node ((GtkTextView *)widget);
|
||||
gtk_style_context_save_to_node (context, text_node);
|
||||
|
||||
gtk_style_context_get_color (context, &color);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
gdk_cairo_set_source_rgba (cr, &color);
|
||||
}
|
||||
|
||||
/* Returns a GSList of (referenced) widgets encountered while drawing.
|
||||
*/
|
||||
static void
|
||||
text_renderer_end (GtkTextRenderer *text_renderer)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
|
||||
cairo_restore (text_renderer->cr);
|
||||
|
||||
context = gtk_widget_get_style_context (text_renderer->widget);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
|
||||
text_renderer->widget = NULL;
|
||||
text_renderer->cr = NULL;
|
||||
|
||||
if (text_renderer->error_color)
|
||||
{
|
||||
gdk_rgba_free (text_renderer->error_color);
|
||||
text_renderer->error_color = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_region_t *
|
||||
get_selected_clip (GtkTextRenderer *text_renderer,
|
||||
PangoLayout *layout,
|
||||
PangoLayoutLine *line,
|
||||
int x,
|
||||
int y,
|
||||
int height,
|
||||
int start_index,
|
||||
int end_index)
|
||||
{
|
||||
gint *ranges;
|
||||
gint n_ranges, i;
|
||||
cairo_region_t *clip_region = cairo_region_create ();
|
||||
|
||||
pango_layout_line_get_x_ranges (line, start_index, end_index, &ranges, &n_ranges);
|
||||
|
||||
for (i=0; i < n_ranges; i++)
|
||||
{
|
||||
GdkRectangle rect;
|
||||
|
||||
rect.x = x + PANGO_PIXELS (ranges[2*i]);
|
||||
rect.y = y;
|
||||
rect.width = PANGO_PIXELS (ranges[2*i + 1]) - PANGO_PIXELS (ranges[2*i]);
|
||||
rect.height = height;
|
||||
|
||||
cairo_region_union_rectangle (clip_region, &rect);
|
||||
}
|
||||
|
||||
g_free (ranges);
|
||||
return clip_region;
|
||||
}
|
||||
|
||||
static void
|
||||
render_para (GtkTextRenderer *text_renderer,
|
||||
GtkTextLineDisplay *line_display,
|
||||
int selection_start_index,
|
||||
int selection_end_index)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
PangoLayout *layout = line_display->layout;
|
||||
int byte_offset = 0;
|
||||
PangoLayoutIter *iter;
|
||||
int screen_width;
|
||||
GdkRGBA *selection;
|
||||
gboolean first = TRUE;
|
||||
GtkCssNode *selection_node;
|
||||
|
||||
iter = pango_layout_get_iter (layout);
|
||||
screen_width = line_display->total_width;
|
||||
|
||||
context = gtk_widget_get_style_context (text_renderer->widget);
|
||||
selection_node = gtk_text_view_get_selection_node ((GtkTextView*)text_renderer->widget);
|
||||
gtk_style_context_save_to_node (context, selection_node);
|
||||
|
||||
gtk_style_context_get (context, "background-color", &selection, NULL);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
|
||||
do
|
||||
{
|
||||
PangoLayoutLine *line = pango_layout_iter_get_line_readonly (iter);
|
||||
int selection_y, selection_height;
|
||||
int first_y, last_y;
|
||||
PangoRectangle line_rect;
|
||||
int baseline;
|
||||
gboolean at_last_line;
|
||||
|
||||
pango_layout_iter_get_line_extents (iter, NULL, &line_rect);
|
||||
baseline = pango_layout_iter_get_baseline (iter);
|
||||
pango_layout_iter_get_line_yrange (iter, &first_y, &last_y);
|
||||
|
||||
/* Adjust for margins */
|
||||
|
||||
line_rect.x += line_display->x_offset * PANGO_SCALE;
|
||||
line_rect.y += line_display->top_margin * PANGO_SCALE;
|
||||
baseline += line_display->top_margin * PANGO_SCALE;
|
||||
|
||||
/* Selection is the height of the line, plus top/bottom
|
||||
* margin if we're the first/last line
|
||||
*/
|
||||
selection_y = PANGO_PIXELS (first_y) + line_display->top_margin;
|
||||
selection_height = PANGO_PIXELS (last_y) - PANGO_PIXELS (first_y);
|
||||
|
||||
if (first)
|
||||
{
|
||||
selection_y -= line_display->top_margin;
|
||||
selection_height += line_display->top_margin;
|
||||
}
|
||||
|
||||
at_last_line = pango_layout_iter_at_last_line (iter);
|
||||
if (at_last_line)
|
||||
selection_height += line_display->bottom_margin;
|
||||
|
||||
first = FALSE;
|
||||
|
||||
if (selection_start_index < byte_offset &&
|
||||
selection_end_index > line->length + byte_offset) /* All selected */
|
||||
{
|
||||
cairo_t *cr = text_renderer->cr;
|
||||
|
||||
cairo_save (cr);
|
||||
gdk_cairo_set_source_rgba (cr, selection);
|
||||
cairo_rectangle (cr,
|
||||
line_display->left_margin, selection_y,
|
||||
screen_width, selection_height);
|
||||
cairo_fill (cr);
|
||||
cairo_restore(cr);
|
||||
|
||||
text_renderer_set_state (text_renderer, SELECTED);
|
||||
pango_renderer_draw_layout_line (PANGO_RENDERER (text_renderer),
|
||||
line,
|
||||
line_rect.x,
|
||||
baseline);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (line_display->pg_bg_rgba)
|
||||
{
|
||||
cairo_t *cr = text_renderer->cr;
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
gdk_cairo_set_source_rgba (text_renderer->cr, line_display->pg_bg_rgba);
|
||||
cairo_rectangle (cr,
|
||||
line_display->left_margin, selection_y,
|
||||
screen_width, selection_height);
|
||||
cairo_fill (cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
text_renderer_set_state (text_renderer, NORMAL);
|
||||
pango_renderer_draw_layout_line (PANGO_RENDERER (text_renderer),
|
||||
line,
|
||||
line_rect.x,
|
||||
baseline);
|
||||
|
||||
/* Check if some part of the line is selected; the newline
|
||||
* that is after line->length for the last line of the
|
||||
* paragraph counts as part of the line for this
|
||||
*/
|
||||
if ((selection_start_index < byte_offset + line->length ||
|
||||
(selection_start_index == byte_offset + line->length && pango_layout_iter_at_last_line (iter))) &&
|
||||
selection_end_index > byte_offset)
|
||||
{
|
||||
cairo_t *cr = text_renderer->cr;
|
||||
cairo_region_t *clip_region = get_selected_clip (text_renderer, layout, line,
|
||||
line_display->x_offset,
|
||||
selection_y,
|
||||
selection_height,
|
||||
selection_start_index, selection_end_index);
|
||||
|
||||
cairo_save (cr);
|
||||
gdk_cairo_region (cr, clip_region);
|
||||
cairo_clip (cr);
|
||||
cairo_region_destroy (clip_region);
|
||||
|
||||
gdk_cairo_set_source_rgba (cr, selection);
|
||||
cairo_rectangle (cr,
|
||||
PANGO_PIXELS (line_rect.x),
|
||||
selection_y,
|
||||
PANGO_PIXELS (line_rect.width),
|
||||
selection_height);
|
||||
cairo_fill (cr);
|
||||
|
||||
text_renderer_set_state (text_renderer, SELECTED);
|
||||
pango_renderer_draw_layout_line (PANGO_RENDERER (text_renderer),
|
||||
line,
|
||||
line_rect.x,
|
||||
baseline);
|
||||
|
||||
cairo_restore (cr);
|
||||
|
||||
/* Paint in the ends of the line */
|
||||
if (line_rect.x > line_display->left_margin * PANGO_SCALE &&
|
||||
((line_display->direction == GTK_TEXT_DIR_LTR && selection_start_index < byte_offset) ||
|
||||
(line_display->direction == GTK_TEXT_DIR_RTL && selection_end_index > byte_offset + line->length)))
|
||||
{
|
||||
cairo_save (cr);
|
||||
|
||||
gdk_cairo_set_source_rgba (cr, selection);
|
||||
cairo_rectangle (cr,
|
||||
line_display->left_margin,
|
||||
selection_y,
|
||||
PANGO_PIXELS (line_rect.x) - line_display->left_margin,
|
||||
selection_height);
|
||||
cairo_fill (cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
if (line_rect.x + line_rect.width <
|
||||
(screen_width + line_display->left_margin) * PANGO_SCALE &&
|
||||
((line_display->direction == GTK_TEXT_DIR_LTR && selection_end_index > byte_offset + line->length) ||
|
||||
(line_display->direction == GTK_TEXT_DIR_RTL && selection_start_index < byte_offset)))
|
||||
{
|
||||
int nonlayout_width;
|
||||
|
||||
nonlayout_width =
|
||||
line_display->left_margin + screen_width -
|
||||
PANGO_PIXELS (line_rect.x) - PANGO_PIXELS (line_rect.width);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
gdk_cairo_set_source_rgba (cr, selection);
|
||||
cairo_rectangle (cr,
|
||||
PANGO_PIXELS (line_rect.x) + PANGO_PIXELS (line_rect.width),
|
||||
selection_y,
|
||||
nonlayout_width,
|
||||
selection_height);
|
||||
cairo_fill (cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
}
|
||||
else if (line_display->has_block_cursor &&
|
||||
gtk_widget_has_focus (text_renderer->widget) &&
|
||||
byte_offset <= line_display->insert_index &&
|
||||
(line_display->insert_index < byte_offset + line->length ||
|
||||
(at_last_line && line_display->insert_index == byte_offset + line->length)))
|
||||
{
|
||||
GdkRectangle cursor_rect;
|
||||
GdkRGBA cursor_color;
|
||||
cairo_t *cr = text_renderer->cr;
|
||||
|
||||
/* we draw text using base color on filled cursor rectangle of cursor color
|
||||
* (normally white on black) */
|
||||
_gtk_style_context_get_cursor_color (context, &cursor_color, NULL);
|
||||
|
||||
cursor_rect.x = line_display->x_offset + line_display->block_cursor.x;
|
||||
cursor_rect.y = line_display->block_cursor.y + line_display->top_margin;
|
||||
cursor_rect.width = line_display->block_cursor.width;
|
||||
cursor_rect.height = line_display->block_cursor.height;
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
gdk_cairo_rectangle (cr, &cursor_rect);
|
||||
cairo_clip (cr);
|
||||
|
||||
gdk_cairo_set_source_rgba (cr, &cursor_color);
|
||||
cairo_paint (cr);
|
||||
|
||||
/* draw text under the cursor if any */
|
||||
if (!line_display->cursor_at_line_end)
|
||||
{
|
||||
GdkRGBA *color;
|
||||
|
||||
gtk_style_context_get (context, "background-color", &color, NULL);
|
||||
|
||||
gdk_cairo_set_source_rgba (cr, color);
|
||||
|
||||
text_renderer_set_state (text_renderer, CURSOR);
|
||||
|
||||
pango_renderer_draw_layout_line (PANGO_RENDERER (text_renderer),
|
||||
line,
|
||||
line_rect.x,
|
||||
baseline);
|
||||
gdk_rgba_free (color);
|
||||
}
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
}
|
||||
|
||||
byte_offset += line->length;
|
||||
}
|
||||
while (pango_layout_iter_next_line (iter));
|
||||
|
||||
gdk_rgba_free (selection);
|
||||
pango_layout_iter_free (iter);
|
||||
}
|
||||
|
||||
static GtkTextRenderer *
|
||||
get_text_renderer (void)
|
||||
{
|
||||
static GtkTextRenderer *text_renderer = NULL;
|
||||
|
||||
if (!text_renderer)
|
||||
text_renderer = g_object_new (GTK_TYPE_TEXT_RENDERER, NULL);
|
||||
|
||||
return text_renderer;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_text_layout_snapshot (GtkTextLayout *layout,
|
||||
GtkWidget *widget,
|
||||
GtkSnapshot *snapshot,
|
||||
const GdkRectangle *clip)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
gint offset_y;
|
||||
GtkTextRenderer *text_renderer;
|
||||
GtkTextIter selection_start, selection_end;
|
||||
gboolean have_selection;
|
||||
GSList *line_list;
|
||||
GSList *tmp_list;
|
||||
cairo_t *cr;
|
||||
|
||||
g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
|
||||
g_return_if_fail (layout->default_style != NULL);
|
||||
g_return_if_fail (layout->buffer != NULL);
|
||||
g_return_if_fail (snapshot != NULL);
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
|
||||
line_list = gtk_text_layout_get_lines (layout, clip->y, clip->y + clip->height, &offset_y);
|
||||
|
||||
if (line_list == NULL)
|
||||
return; /* nothing on the screen */
|
||||
|
||||
cr = gtk_snapshot_append_cairo (snapshot,
|
||||
&GRAPHENE_RECT_INIT(clip->x, clip->y, clip->width, clip->height));
|
||||
text_renderer = get_text_renderer ();
|
||||
text_renderer_begin (text_renderer, widget, cr);
|
||||
|
||||
/* text_renderer_begin/end does cairo_save/restore */
|
||||
cairo_translate (cr, 0, offset_y);
|
||||
|
||||
gtk_text_layout_wrap_loop_start (layout);
|
||||
|
||||
have_selection = gtk_text_buffer_get_selection_bounds (layout->buffer,
|
||||
&selection_start,
|
||||
&selection_end);
|
||||
|
||||
tmp_list = line_list;
|
||||
while (tmp_list != NULL)
|
||||
{
|
||||
GtkTextLineDisplay *line_display;
|
||||
gint selection_start_index = -1;
|
||||
gint selection_end_index = -1;
|
||||
|
||||
GtkTextLine *line = tmp_list->data;
|
||||
|
||||
line_display = gtk_text_layout_get_line_display (layout, line, FALSE);
|
||||
|
||||
if (line_display->height > 0)
|
||||
{
|
||||
g_assert (line_display->layout != NULL);
|
||||
|
||||
if (have_selection)
|
||||
{
|
||||
GtkTextIter line_start, line_end;
|
||||
gint byte_count;
|
||||
|
||||
gtk_text_layout_get_iter_at_line (layout,
|
||||
&line_start,
|
||||
line, 0);
|
||||
line_end = line_start;
|
||||
if (!gtk_text_iter_ends_line (&line_end))
|
||||
gtk_text_iter_forward_to_line_end (&line_end);
|
||||
byte_count = gtk_text_iter_get_visible_line_index (&line_end);
|
||||
|
||||
if (gtk_text_iter_compare (&selection_start, &line_end) <= 0 &&
|
||||
gtk_text_iter_compare (&selection_end, &line_start) >= 0)
|
||||
{
|
||||
if (gtk_text_iter_compare (&selection_start, &line_start) >= 0)
|
||||
selection_start_index = gtk_text_iter_get_visible_line_index (&selection_start);
|
||||
else
|
||||
selection_start_index = -1;
|
||||
|
||||
if (gtk_text_iter_compare (&selection_end, &line_end) <= 0)
|
||||
selection_end_index = gtk_text_iter_get_visible_line_index (&selection_end);
|
||||
else
|
||||
selection_end_index = byte_count + 1; /* + 1 to flag past-the-end */
|
||||
}
|
||||
}
|
||||
|
||||
render_para (text_renderer, line_display,
|
||||
selection_start_index, selection_end_index);
|
||||
|
||||
/* We paint the cursors last, because they overlap another chunk
|
||||
* and need to appear on top.
|
||||
*/
|
||||
if (line_display->cursors != NULL)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < line_display->cursors->len; i++)
|
||||
{
|
||||
int index;
|
||||
PangoDirection dir;
|
||||
|
||||
index = g_array_index(line_display->cursors, int, i);
|
||||
dir = (line_display->direction == GTK_TEXT_DIR_RTL) ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR;
|
||||
gtk_render_insertion_cursor (context, cr,
|
||||
line_display->x_offset, line_display->top_margin,
|
||||
line_display->layout, index, dir);
|
||||
}
|
||||
}
|
||||
} /* line_display->height > 0 */
|
||||
|
||||
cairo_translate (cr, 0, line_display->height);
|
||||
gtk_text_layout_free_line_display (layout, line_display);
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
|
||||
gtk_text_layout_wrap_loop_end (layout);
|
||||
text_renderer_end (text_renderer);
|
||||
|
||||
g_slist_free (line_list);
|
||||
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
/* gtktextdisplay.c - display layed-out text
|
||||
*
|
||||
* Copyright (c) 1992-1994 The Regents of the University of California.
|
||||
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
|
||||
* Copyright (c) 2000 Red Hat, Inc.
|
||||
* Tk->Gtk port by Havoc Pennington
|
||||
*
|
||||
* This file can be used under your choice of two licenses, the LGPL
|
||||
* and the original Tk license.
|
||||
*
|
||||
* LGPL:
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Original Tk license:
|
||||
*
|
||||
* This software is copyrighted by the Regents of the University of
|
||||
* California, Sun Microsystems, Inc., and other parties. The
|
||||
* following terms apply to all files associated with the software
|
||||
* unless explicitly disclaimed in individual files.
|
||||
*
|
||||
* The authors hereby grant permission to use, copy, modify,
|
||||
* distribute, and license this software and its documentation for any
|
||||
* purpose, provided that existing copyright notices are retained in
|
||||
* all copies and that this notice is included verbatim in any
|
||||
* distributions. No written agreement, license, or royalty fee is
|
||||
* required for any of the authorized uses. Modifications to this
|
||||
* software may be copyrighted by their authors and need not follow
|
||||
* the licensing terms described here, provided that the new terms are
|
||||
* clearly indicated on the first page of each file where they apply.
|
||||
*
|
||||
* IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY
|
||||
* PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
|
||||
* DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION,
|
||||
* OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
|
||||
* NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
|
||||
* AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
|
||||
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
* GOVERNMENT USE: If you are acquiring this software on behalf of the
|
||||
* U.S. government, the Government shall have only "Restricted Rights"
|
||||
* in the software and related documentation as defined in the Federal
|
||||
* Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
|
||||
* are acquiring the software on behalf of the Department of Defense,
|
||||
* the software shall be classified as "Commercial Computer Software"
|
||||
* and the Government shall have only "Restricted Rights" as defined
|
||||
* in Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the
|
||||
* foregoing, the authors grant the U.S. Government and others acting
|
||||
* in its behalf permission to use and distribute the software in
|
||||
* accordance with the terms specified in this license.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_TEXT_DISPLAY_PRIVATE_H__
|
||||
#define __GTK_TEXT_DISPLAY_PRIVATE_H__
|
||||
|
||||
#include "gtktextlayoutprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* A semi-public header intended for use by code that also
|
||||
* uses GtkTextLayout
|
||||
*/
|
||||
|
||||
/* The drawable should be pre-initialized to your preferred background.
|
||||
* widget - Widget to grab some style info from
|
||||
* snapshot - Snapshot to render to, matrix set so that (0, 0)
|
||||
* is the top left of the layout
|
||||
* clip - visible area
|
||||
*/
|
||||
void gtk_text_layout_snapshot (GtkTextLayout *layout,
|
||||
GtkWidget *widget,
|
||||
GtkSnapshot *snapshot,
|
||||
const GdkRectangle *clip);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_TEXT_DISPLAY_PRIVATE_H__ */
|
||||
@@ -5358,6 +5358,25 @@ gtk_text_iter_equal (const GtkTextIter *lhs,
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_text_iter_same_line (const GtkTextIter *lhs,
|
||||
const GtkTextIter *rhs)
|
||||
{
|
||||
GtkTextRealIter *real_lhs;
|
||||
GtkTextRealIter *real_rhs;
|
||||
|
||||
real_lhs = gtk_text_iter_make_surreal (lhs);
|
||||
real_rhs = gtk_text_iter_make_surreal (rhs);
|
||||
|
||||
if (real_lhs == NULL || real_rhs == NULL)
|
||||
return FALSE;
|
||||
|
||||
check_invariants (lhs);
|
||||
check_invariants (rhs);
|
||||
|
||||
return real_lhs->line == real_rhs->line;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_text_iter_compare:
|
||||
* @lhs: a #GtkTextIter
|
||||
|
||||
@@ -41,6 +41,8 @@ gboolean _gtk_text_iter_forward_indexable_segment (GtkTextIter
|
||||
gboolean _gtk_text_iter_backward_indexable_segment (GtkTextIter *iter);
|
||||
gint _gtk_text_iter_get_segment_byte (const GtkTextIter *iter);
|
||||
gint _gtk_text_iter_get_segment_char (const GtkTextIter *iter);
|
||||
gboolean _gtk_text_iter_same_line (const GtkTextIter *lhs,
|
||||
const GtkTextIter *rhs);
|
||||
|
||||
gboolean gtk_text_iter_get_attributes (const GtkTextIter *iter,
|
||||
GtkTextAttributes *values);
|
||||
|
||||
+686
-264
File diff suppressed because it is too large
Load Diff
+27
-77
@@ -138,11 +138,6 @@ struct _GtkTextLayout
|
||||
* over long runs with the same style. */
|
||||
GtkTextAttributes *one_style_cache;
|
||||
|
||||
/* A cache of one line display. Getting the same line
|
||||
* many times in a row is the most common case.
|
||||
*/
|
||||
GtkTextLineDisplay *one_display_cache;
|
||||
|
||||
/* Whether we are allowed to wrap right now */
|
||||
gint wrap_loop_count;
|
||||
|
||||
@@ -223,6 +218,12 @@ struct _GtkTextLineDisplay
|
||||
PangoLayout *layout;
|
||||
GArray *cursors; /* indexes of cursors in the PangoLayout */
|
||||
|
||||
/* GSequenceIter backpointer for use within cache */
|
||||
GSequenceIter *cache_iter;
|
||||
|
||||
/* GQueue link for use in MRU to help cull cache */
|
||||
GList mru_link;
|
||||
|
||||
GtkTextDirection direction;
|
||||
|
||||
gint width; /* Width of layout */
|
||||
@@ -246,224 +247,173 @@ struct _GtkTextLineDisplay
|
||||
guint cursor_at_line_end : 1;
|
||||
guint size_only : 1;
|
||||
|
||||
GdkRGBA *pg_bg_rgba;
|
||||
GdkRGBA pg_bg_rgba;
|
||||
guint pg_bg_rgba_set : 1;
|
||||
};
|
||||
|
||||
#ifdef GTK_COMPILATION
|
||||
extern G_GNUC_INTERNAL PangoAttrType gtk_text_attr_appearance_type;
|
||||
#endif
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gtk_text_layout_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkTextLayout* gtk_text_layout_new (void);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_set_buffer (GtkTextLayout *layout,
|
||||
GtkTextBuffer *buffer);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkTextBuffer *gtk_text_layout_get_buffer (GtkTextLayout *layout);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_set_default_style (GtkTextLayout *layout,
|
||||
GtkTextAttributes *values);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_set_contexts (GtkTextLayout *layout,
|
||||
PangoContext *ltr_context,
|
||||
PangoContext *rtl_context);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_set_cursor_direction (GtkTextLayout *layout,
|
||||
GtkTextDirection direction);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_set_overwrite_mode (GtkTextLayout *layout,
|
||||
gboolean overwrite);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_set_keyboard_direction (GtkTextLayout *layout,
|
||||
GtkTextDirection keyboard_dir);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_default_style_changed (GtkTextLayout *layout);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_set_screen_width (GtkTextLayout *layout,
|
||||
gint width);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_set_preedit_string (GtkTextLayout *layout,
|
||||
const gchar *preedit_string,
|
||||
PangoAttrList *preedit_attrs,
|
||||
gint cursor_pos);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_set_cursor_visible (GtkTextLayout *layout,
|
||||
gboolean cursor_visible);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_text_layout_get_cursor_visible (GtkTextLayout *layout);
|
||||
|
||||
/* Getting the size or the lines potentially results in a call to
|
||||
* recompute, which is pretty massively expensive. Thus it should
|
||||
* basically only be done in an idle handler.
|
||||
*
|
||||
* Long-term, we would really like to be able to do these without
|
||||
* a full recompute so they may get cheaper over time.
|
||||
*/
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_get_size (GtkTextLayout *layout,
|
||||
gint *width,
|
||||
gint *height);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GSList* gtk_text_layout_get_lines (GtkTextLayout *layout,
|
||||
/* [top_y, bottom_y) */
|
||||
gint top_y,
|
||||
gint bottom_y,
|
||||
gint *first_line_y);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_wrap_loop_start (GtkTextLayout *layout);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_wrap_loop_end (GtkTextLayout *layout);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkTextLineDisplay* gtk_text_layout_get_line_display (GtkTextLayout *layout,
|
||||
GtkTextLine *line,
|
||||
gboolean size_only);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_free_line_display (GtkTextLayout *layout,
|
||||
GtkTextLineDisplay *display);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkTextLineDisplay *gtk_text_line_display_ref (GtkTextLineDisplay *display);
|
||||
void gtk_text_line_display_unref (GtkTextLineDisplay *display);
|
||||
gint gtk_text_line_display_compare (const GtkTextLineDisplay *display1,
|
||||
const GtkTextLineDisplay *display2,
|
||||
GtkTextLayout *layout);
|
||||
|
||||
void gtk_text_layout_get_line_at_y (GtkTextLayout *layout,
|
||||
GtkTextIter *target_iter,
|
||||
gint y,
|
||||
gint *line_top);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_text_layout_get_iter_at_pixel (GtkTextLayout *layout,
|
||||
GtkTextIter *iter,
|
||||
gint x,
|
||||
gint y);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_text_layout_get_iter_at_position (GtkTextLayout *layout,
|
||||
GtkTextIter *iter,
|
||||
gint *trailing,
|
||||
gint x,
|
||||
gint y);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_invalidate (GtkTextLayout *layout,
|
||||
const GtkTextIter *start,
|
||||
const GtkTextIter *end);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_invalidate_cursors(GtkTextLayout *layout,
|
||||
const GtkTextIter *start,
|
||||
const GtkTextIter *end);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_free_line_data (GtkTextLayout *layout,
|
||||
GtkTextLine *line,
|
||||
GtkTextLineData *line_data);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_text_layout_is_valid (GtkTextLayout *layout);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_validate_yrange (GtkTextLayout *layout,
|
||||
GtkTextIter *anchor_line,
|
||||
gint y0_,
|
||||
gint y1_);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_validate (GtkTextLayout *layout,
|
||||
gint max_pixels);
|
||||
|
||||
/* This function should return the passed-in line data,
|
||||
* OR remove the existing line data from the line, and
|
||||
* return a NEW line data after adding it to the line.
|
||||
* That is, invariant after calling the callback is that
|
||||
* there should be exactly one line data for this view
|
||||
* stored on the btree line.
|
||||
*/
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkTextLineData* gtk_text_layout_wrap (GtkTextLayout *layout,
|
||||
GtkTextLine *line,
|
||||
GtkTextLineData *line_data); /* may be NULL */
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkTextLineData *line_data);
|
||||
void gtk_text_layout_changed (GtkTextLayout *layout,
|
||||
gint y,
|
||||
gint old_height,
|
||||
gint new_height);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_cursors_changed (GtkTextLayout *layout,
|
||||
gint y,
|
||||
gint old_height,
|
||||
gint new_height);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_get_iter_location (GtkTextLayout *layout,
|
||||
const GtkTextIter *iter,
|
||||
GdkRectangle *rect);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_get_line_yrange (GtkTextLayout *layout,
|
||||
const GtkTextIter *iter,
|
||||
gint *y,
|
||||
gint *height);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_get_cursor_locations (GtkTextLayout *layout,
|
||||
GtkTextIter *iter,
|
||||
GdkRectangle *strong_pos,
|
||||
GdkRectangle *weak_pos);
|
||||
GtkTextLineDisplay *gtk_text_layout_create_display (GtkTextLayout *layout,
|
||||
GtkTextLine *line,
|
||||
gboolean size_only);
|
||||
void gtk_text_layout_update_display_cursors (GtkTextLayout *layout,
|
||||
GtkTextLine *line,
|
||||
GtkTextLineDisplay *display);
|
||||
gboolean _gtk_text_layout_get_block_cursor (GtkTextLayout *layout,
|
||||
GdkRectangle *pos);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_text_layout_clamp_iter_to_vrange (GtkTextLayout *layout,
|
||||
GtkTextIter *iter,
|
||||
gint top,
|
||||
gint bottom);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_text_layout_move_iter_to_line_end (GtkTextLayout *layout,
|
||||
GtkTextIter *iter,
|
||||
gint direction);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
|
||||
GtkTextIter *iter);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_text_layout_move_iter_to_next_line (GtkTextLayout *layout,
|
||||
GtkTextIter *iter);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_move_iter_to_x (GtkTextLayout *layout,
|
||||
GtkTextIter *iter,
|
||||
gint x);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_text_layout_move_iter_visually (GtkTextLayout *layout,
|
||||
GtkTextIter *iter,
|
||||
gint count);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_text_layout_iter_starts_line (GtkTextLayout *layout,
|
||||
const GtkTextIter *iter);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_get_iter_at_line (GtkTextLayout *layout,
|
||||
GtkTextIter *iter,
|
||||
GtkTextLine *line,
|
||||
gint byte_offset);
|
||||
|
||||
/* Don't use these. Use gtk_text_view_add_child_at_anchor().
|
||||
* These functions are defined in gtktextchild.c, but here
|
||||
* since they are semi-public and require GtkTextLayout to
|
||||
* be declared.
|
||||
*/
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_child_anchor_register_child (GtkTextChildAnchor *anchor,
|
||||
GtkWidget *child,
|
||||
GtkTextLayout *layout);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_child_anchor_unregister_child (GtkTextChildAnchor *anchor,
|
||||
GtkWidget *child);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_child_anchor_queue_resize (GtkTextChildAnchor *anchor,
|
||||
GtkTextLayout *layout);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_anchored_child_set_layout (GtkWidget *child,
|
||||
GtkTextLayout *layout);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_layout_spew (GtkTextLayout *layout);
|
||||
|
||||
void gtk_text_layout_snapshot (GtkTextLayout *layout,
|
||||
GtkWidget *widget,
|
||||
GtkSnapshot *snapshot,
|
||||
const GdkRectangle *clip,
|
||||
float cursor_alpha);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_TEXT_LAYOUT_PRIVATE_H__ */
|
||||
|
||||
@@ -0,0 +1,716 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
* Copyright (C) 2019 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtktextbtree.h"
|
||||
#include "gtktextbufferprivate.h"
|
||||
#include "gtktextiterprivate.h"
|
||||
#include "gtktextlinedisplaycacheprivate.h"
|
||||
|
||||
#define MRU_MAX_SIZE 250
|
||||
#define BLOW_CACHE_TIMEOUT_SEC 20
|
||||
#define DEBUG_LINE_DISPLAY_CACHE 0
|
||||
|
||||
struct _GtkTextLineDisplayCache
|
||||
{
|
||||
GSequence *sorted_by_line;
|
||||
GHashTable *line_to_display;
|
||||
GtkTextLine *cursor_line;
|
||||
GQueue mru;
|
||||
GSource *evict_source;
|
||||
|
||||
#if DEBUG_LINE_DISPLAY_CACHE
|
||||
guint log_source;
|
||||
gint hits;
|
||||
gint misses;
|
||||
gint inval;
|
||||
gint inval_cursors;
|
||||
gint inval_by_line;
|
||||
gint inval_by_range;
|
||||
gint inval_by_y_range;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if DEBUG_LINE_DISPLAY_CACHE
|
||||
# define STAT_ADD(val,n) ((val) += n)
|
||||
# define STAT_INC(val) STAT_ADD(val,1)
|
||||
static gboolean
|
||||
dump_stats (gpointer data)
|
||||
{
|
||||
GtkTextLineDisplayCache *cache = data;
|
||||
g_printerr ("%p: size=%u hits=%d misses=%d inval_total=%d "
|
||||
"inval_cursors=%d inval_by_line=%d "
|
||||
"inval_by_range=%d inval_by_y_range=%d\n",
|
||||
cache, g_hash_table_size (cache->line_to_display),
|
||||
cache->hits, cache->misses,
|
||||
cache->inval, cache->inval_cursors,
|
||||
cache->inval_by_line, cache->inval_by_range,
|
||||
cache->inval_by_y_range);
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
#else
|
||||
# define STAT_ADD(val,n)
|
||||
# define STAT_INC(val)
|
||||
#endif
|
||||
|
||||
GtkTextLineDisplayCache *
|
||||
gtk_text_line_display_cache_new (void)
|
||||
{
|
||||
GtkTextLineDisplayCache *ret;
|
||||
|
||||
ret = g_slice_new0 (GtkTextLineDisplayCache);
|
||||
ret->sorted_by_line = g_sequence_new ((GDestroyNotify)gtk_text_line_display_unref);
|
||||
ret->line_to_display = g_hash_table_new (NULL, NULL);
|
||||
|
||||
#if DEBUG_LINE_DISPLAY_CACHE
|
||||
ret->log_source = g_timeout_add_seconds (1, dump_stats, ret);
|
||||
#endif
|
||||
|
||||
return g_steal_pointer (&ret);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_text_line_display_cache_free (GtkTextLineDisplayCache *cache)
|
||||
{
|
||||
#if DEBUG_LINE_DISPLAY_CACHE
|
||||
g_clear_handle_id (&cache->log_source, g_source_remove);
|
||||
#endif
|
||||
|
||||
g_clear_pointer (&cache->evict_source, g_source_destroy);
|
||||
g_clear_pointer (&cache->sorted_by_line, g_sequence_free);
|
||||
g_clear_pointer (&cache->line_to_display, g_hash_table_unref);
|
||||
g_slice_free (GtkTextLineDisplayCache, cache);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_text_line_display_cache_blow_cb (gpointer data)
|
||||
{
|
||||
GtkTextLineDisplayCache *cache = data;
|
||||
|
||||
g_assert (cache != NULL);
|
||||
|
||||
#if DEBUG_LINE_DISPLAY_CACHE
|
||||
g_printerr ("Evicting GtkTextLineDisplayCache\n");
|
||||
#endif
|
||||
|
||||
cache->evict_source = NULL;
|
||||
|
||||
gtk_text_line_display_cache_invalidate (cache);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_text_line_display_cache_delay_eviction (GtkTextLineDisplayCache *cache)
|
||||
{
|
||||
g_assert (cache != NULL);
|
||||
|
||||
if (cache->evict_source != NULL)
|
||||
{
|
||||
gint64 deadline;
|
||||
|
||||
deadline = g_get_monotonic_time () + (BLOW_CACHE_TIMEOUT_SEC * G_USEC_PER_SEC);
|
||||
g_source_set_ready_time (cache->evict_source, deadline);
|
||||
}
|
||||
else
|
||||
{
|
||||
guint tag;
|
||||
|
||||
tag = g_timeout_add_seconds (BLOW_CACHE_TIMEOUT_SEC,
|
||||
gtk_text_line_display_cache_blow_cb,
|
||||
cache);
|
||||
cache->evict_source = g_main_context_find_source_by_id (NULL, tag);
|
||||
g_source_set_name (cache->evict_source, "[gtk+] gtk_text_line_display_cache_blow_cb");
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG_LINE_DISPLAY_CACHE
|
||||
static void
|
||||
check_disposition (GtkTextLineDisplayCache *cache,
|
||||
GtkTextLayout *layout)
|
||||
{
|
||||
GSequenceIter *iter;
|
||||
gint last = G_MAXUINT;
|
||||
|
||||
g_assert (cache != NULL);
|
||||
g_assert (cache->sorted_by_line != NULL);
|
||||
g_assert (cache->line_to_display != NULL);
|
||||
|
||||
for (iter = g_sequence_get_begin_iter (cache->sorted_by_line);
|
||||
!g_sequence_iter_is_end (iter);
|
||||
iter = g_sequence_iter_next (iter))
|
||||
{
|
||||
GtkTextLineDisplay *display = g_sequence_get (iter);
|
||||
GtkTextIter text_iter;
|
||||
guint line;
|
||||
|
||||
gtk_text_layout_get_iter_at_line (layout, &text_iter, display->line, 0);
|
||||
line = gtk_text_iter_get_line (&text_iter);
|
||||
|
||||
g_assert_cmpint (line, >, last);
|
||||
|
||||
last = line;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
gtk_text_line_display_cache_take_display (GtkTextLineDisplayCache *cache,
|
||||
GtkTextLineDisplay *display,
|
||||
GtkTextLayout *layout)
|
||||
{
|
||||
g_assert (cache != NULL);
|
||||
g_assert (display != NULL);
|
||||
g_assert (display->line != NULL);
|
||||
g_assert (display->cache_iter == NULL);
|
||||
g_assert (display->mru_link.data == display);
|
||||
g_assert (display->mru_link.prev == NULL);
|
||||
g_assert (display->mru_link.next == NULL);
|
||||
g_assert (g_hash_table_lookup (cache->line_to_display, display->line) == NULL);
|
||||
|
||||
#if DEBUG_LINE_DISPLAY_CACHE
|
||||
check_disposition (cache, layout);
|
||||
#endif
|
||||
|
||||
display->cache_iter =
|
||||
g_sequence_insert_sorted (cache->sorted_by_line,
|
||||
display,
|
||||
(GCompareDataFunc) gtk_text_line_display_compare,
|
||||
layout);
|
||||
g_hash_table_insert (cache->line_to_display, display->line, display);
|
||||
g_queue_push_head_link (&cache->mru, &display->mru_link);
|
||||
|
||||
/* Cull the cache if we're at capacity */
|
||||
while (cache->mru.length > MRU_MAX_SIZE)
|
||||
{
|
||||
display = g_queue_peek_tail (&cache->mru);
|
||||
|
||||
gtk_text_line_display_cache_invalidate_display (cache, display, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* gtk_text_line_display_cache_invalidate_display:
|
||||
* @cache: a GtkTextLineDisplayCache
|
||||
* @display: a GtkTextLineDisplay
|
||||
* @cursors_only: if only the cursor positions should be invalidated
|
||||
*
|
||||
* If @cursors_only is TRUE, then only the cursors are invalidated. Otherwise,
|
||||
* @display is removed from the cache.
|
||||
*
|
||||
* Use this function when you already have access to a display as it reduces
|
||||
* some overhead.
|
||||
*/
|
||||
void
|
||||
gtk_text_line_display_cache_invalidate_display (GtkTextLineDisplayCache *cache,
|
||||
GtkTextLineDisplay *display,
|
||||
gboolean cursors_only)
|
||||
{
|
||||
g_assert (cache != NULL);
|
||||
g_assert (display != NULL);
|
||||
g_assert (display->line != NULL);
|
||||
|
||||
if (cursors_only)
|
||||
{
|
||||
g_clear_pointer (&display->cursors, g_array_unref);
|
||||
display->cursors_invalid = TRUE;
|
||||
display->has_block_cursor = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
GSequenceIter *iter = g_steal_pointer (&display->cache_iter);
|
||||
|
||||
if (cache->cursor_line == display->line)
|
||||
cache->cursor_line = NULL;
|
||||
|
||||
g_hash_table_remove (cache->line_to_display, display->line);
|
||||
g_queue_unlink (&cache->mru, &display->mru_link);
|
||||
|
||||
if (iter != NULL)
|
||||
g_sequence_remove (iter);
|
||||
}
|
||||
|
||||
STAT_INC (cache->inval);
|
||||
}
|
||||
|
||||
/*
|
||||
* gtk_text_line_display_cache_get:
|
||||
* @cache: a #GtkTextLineDisplayCache
|
||||
* @layout: a GtkTextLayout
|
||||
* @line: a GtkTextLine
|
||||
* @size_only: if only line sizing is needed
|
||||
*
|
||||
* Gets a GtkTextLineDisplay for @line.
|
||||
*
|
||||
* If no cached display exists, a new display will be created.
|
||||
*
|
||||
* It's possible that calling this function will cause some existing
|
||||
* cached displays to be released and destroyed.
|
||||
*
|
||||
* Returns: (transfer full) (not nullable): a #GtkTextLineDisplay
|
||||
*/
|
||||
GtkTextLineDisplay *
|
||||
gtk_text_line_display_cache_get (GtkTextLineDisplayCache *cache,
|
||||
GtkTextLayout *layout,
|
||||
GtkTextLine *line,
|
||||
gboolean size_only)
|
||||
{
|
||||
GtkTextLineDisplay *display;
|
||||
|
||||
g_assert (cache != NULL);
|
||||
g_assert (layout != NULL);
|
||||
g_assert (line != NULL);
|
||||
|
||||
display = g_hash_table_lookup (cache->line_to_display, line);
|
||||
|
||||
if (display != NULL)
|
||||
{
|
||||
if (size_only || !display->size_only)
|
||||
{
|
||||
STAT_INC (cache->hits);
|
||||
|
||||
if (!size_only && display->line == cache->cursor_line)
|
||||
gtk_text_layout_update_display_cursors (layout, display->line, display);
|
||||
|
||||
/* Move to front of MRU */
|
||||
g_queue_unlink (&cache->mru, &display->mru_link);
|
||||
g_queue_push_head_link (&cache->mru, &display->mru_link);
|
||||
|
||||
return gtk_text_line_display_ref (display);
|
||||
}
|
||||
|
||||
/* We need an updated display that includes more than just
|
||||
* sizing, so we need to drop this entry and force the layout
|
||||
* to create a new one.
|
||||
*/
|
||||
gtk_text_line_display_cache_invalidate_display (cache, display, FALSE);
|
||||
}
|
||||
|
||||
STAT_INC (cache->misses);
|
||||
|
||||
g_assert (!g_hash_table_lookup (cache->line_to_display, line));
|
||||
|
||||
display = gtk_text_layout_create_display (layout, line, size_only);
|
||||
|
||||
g_assert (display != NULL);
|
||||
g_assert (display->line == line);
|
||||
|
||||
if (!size_only)
|
||||
{
|
||||
if (line == cache->cursor_line)
|
||||
gtk_text_layout_update_display_cursors (layout, line, display);
|
||||
|
||||
gtk_text_line_display_cache_take_display (cache,
|
||||
gtk_text_line_display_ref (display),
|
||||
layout);
|
||||
}
|
||||
|
||||
return g_steal_pointer (&display);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_text_line_display_cache_invalidate (GtkTextLineDisplayCache *cache)
|
||||
{
|
||||
g_assert (cache != NULL);
|
||||
g_assert (cache->sorted_by_line != NULL);
|
||||
g_assert (cache->line_to_display != NULL);
|
||||
|
||||
STAT_ADD (cache->inval, g_hash_table_size (cache->line_to_display));
|
||||
|
||||
cache->cursor_line = NULL;
|
||||
|
||||
while (cache->mru.head != NULL)
|
||||
{
|
||||
GtkTextLineDisplay *display = g_queue_peek_head (&cache->mru);
|
||||
|
||||
gtk_text_line_display_cache_invalidate_display (cache, display, FALSE);
|
||||
}
|
||||
|
||||
g_assert (g_hash_table_size (cache->line_to_display) == 0);
|
||||
g_assert (g_sequence_get_length (cache->sorted_by_line) == 0);
|
||||
g_assert (cache->mru.length == 0);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_text_line_display_cache_invalidate_cursors (GtkTextLineDisplayCache *cache,
|
||||
GtkTextLine *line)
|
||||
{
|
||||
GtkTextLineDisplay *display;
|
||||
|
||||
g_assert (cache != NULL);
|
||||
g_assert (line != NULL);
|
||||
|
||||
STAT_INC (cache->inval_cursors);
|
||||
|
||||
display = g_hash_table_lookup (cache->line_to_display, line);
|
||||
|
||||
if (display != NULL)
|
||||
gtk_text_line_display_cache_invalidate_display (cache, display, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* gtk_text_line_display_cache_invalidate_line:
|
||||
* @self: a GtkTextLineDisplayCache
|
||||
* @line: a GtkTextLine
|
||||
*
|
||||
* Removes a cached display for @line.
|
||||
*
|
||||
* Compare to gtk_text_line_display_cache_invalidate_cursors() which
|
||||
* only invalidates the cursors for this row.
|
||||
*/
|
||||
void
|
||||
gtk_text_line_display_cache_invalidate_line (GtkTextLineDisplayCache *cache,
|
||||
GtkTextLine *line)
|
||||
{
|
||||
GtkTextLineDisplay *display;
|
||||
|
||||
g_assert (cache != NULL);
|
||||
g_assert (line != NULL);
|
||||
|
||||
display = g_hash_table_lookup (cache->line_to_display, line);
|
||||
|
||||
if (display != NULL)
|
||||
gtk_text_line_display_cache_invalidate_display (cache, display, FALSE);
|
||||
|
||||
STAT_INC (cache->inval_by_line);
|
||||
}
|
||||
|
||||
static GSequenceIter *
|
||||
find_iter_at_text_iter (GtkTextLineDisplayCache *cache,
|
||||
GtkTextLayout *layout,
|
||||
const GtkTextIter *iter)
|
||||
{
|
||||
GSequenceIter *left;
|
||||
GSequenceIter *right;
|
||||
GSequenceIter *mid;
|
||||
GSequenceIter *end;
|
||||
GtkTextLine *target;
|
||||
guint target_lineno;
|
||||
|
||||
g_assert (cache != NULL);
|
||||
g_assert (iter != NULL);
|
||||
|
||||
if (g_sequence_is_empty (cache->sorted_by_line))
|
||||
return NULL;
|
||||
|
||||
/* gtk_text_iter_get_line() will have cached value */
|
||||
target_lineno = gtk_text_iter_get_line (iter);
|
||||
target = _gtk_text_iter_get_text_line (iter);
|
||||
|
||||
/* Get some iters so we can work with pointer compare */
|
||||
end = g_sequence_get_end_iter (cache->sorted_by_line);
|
||||
left = g_sequence_get_begin_iter (cache->sorted_by_line);
|
||||
right = g_sequence_iter_prev (end);
|
||||
|
||||
/* We already checked for empty above */
|
||||
g_assert (!g_sequence_iter_is_end (left));
|
||||
g_assert (!g_sequence_iter_is_end (right));
|
||||
|
||||
for (;;)
|
||||
{
|
||||
GtkTextLineDisplay *display;
|
||||
guint lineno;
|
||||
|
||||
if (left == right)
|
||||
mid = left;
|
||||
else
|
||||
mid = g_sequence_range_get_midpoint (left, right);
|
||||
|
||||
g_assert (mid != NULL);
|
||||
g_assert (!g_sequence_iter_is_end (mid));
|
||||
|
||||
if (mid == end)
|
||||
break;
|
||||
|
||||
display = g_sequence_get (mid);
|
||||
|
||||
g_assert (display != NULL);
|
||||
g_assert (display->line != NULL);
|
||||
g_assert (display->cache_iter != NULL);
|
||||
|
||||
if (target == display->line)
|
||||
return mid;
|
||||
|
||||
if (right == left)
|
||||
break;
|
||||
|
||||
lineno = _gtk_text_line_get_number (display->line);
|
||||
|
||||
if (target_lineno < lineno)
|
||||
right = mid;
|
||||
else if (target_lineno > lineno)
|
||||
left = g_sequence_iter_next (mid);
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* gtk_text_line_display_cache_invalidate_range:
|
||||
* @cache: a GtkTextLineDisplayCache
|
||||
* @begin: the starting text iter
|
||||
* @end: the ending text iter
|
||||
*
|
||||
* Removes all GtkTextLineDisplay that fall between or including
|
||||
* @begin and @end.
|
||||
*/
|
||||
void
|
||||
gtk_text_line_display_cache_invalidate_range (GtkTextLineDisplayCache *cache,
|
||||
GtkTextLayout *layout,
|
||||
const GtkTextIter *begin,
|
||||
const GtkTextIter *end,
|
||||
gboolean cursors_only)
|
||||
{
|
||||
GSequenceIter *begin_iter;
|
||||
GSequenceIter *end_iter;
|
||||
GSequenceIter *iter;
|
||||
|
||||
g_assert (cache != NULL);
|
||||
g_assert (layout != NULL);
|
||||
g_assert (begin != NULL);
|
||||
g_assert (end != NULL);
|
||||
|
||||
STAT_INC (cache->inval_by_range);
|
||||
|
||||
/* Short-circuit, is_empty() is O(1) */
|
||||
if (g_sequence_is_empty (cache->sorted_by_line))
|
||||
return;
|
||||
|
||||
/* gtk_text_iter_order() preserving const */
|
||||
if (gtk_text_iter_compare (begin, end) > 0)
|
||||
{
|
||||
const GtkTextIter *tmp = begin;
|
||||
end = begin;
|
||||
begin = tmp;
|
||||
}
|
||||
|
||||
/* Common case, begin/end on same line. Just try to find the line by
|
||||
* line number and invalidate it alone.
|
||||
*/
|
||||
if G_LIKELY (_gtk_text_iter_same_line (begin, end))
|
||||
{
|
||||
begin_iter = find_iter_at_text_iter (cache, layout, begin);
|
||||
|
||||
if (begin_iter != NULL)
|
||||
{
|
||||
GtkTextLineDisplay *display = g_sequence_get (begin_iter);
|
||||
|
||||
g_assert (display != NULL);
|
||||
g_assert (display->line != NULL);
|
||||
|
||||
gtk_text_line_display_cache_invalidate_display (cache, display, cursors_only);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find GSequenceIter containing GtkTextLineDisplay that correspond
|
||||
* to each of the text positions.
|
||||
*/
|
||||
begin_iter = find_iter_at_text_iter (cache, layout, begin);
|
||||
end_iter = find_iter_at_text_iter (cache, layout, end);
|
||||
|
||||
/* Short-circuit if we found nothing */
|
||||
if (begin_iter == NULL && end_iter == NULL)
|
||||
return;
|
||||
|
||||
/* If nothing matches the end, we need to walk to the end of our
|
||||
* cached displays. We know there is a non-zero number of items
|
||||
* in the sequence at this point, so we can iter_prev() safely.
|
||||
*/
|
||||
if (end_iter == NULL)
|
||||
end_iter = g_sequence_iter_prev (g_sequence_get_end_iter (cache->sorted_by_line));
|
||||
|
||||
/* If nothing matched the begin, we need to walk starting from
|
||||
* the first display we have cached.
|
||||
*/
|
||||
if (begin_iter == NULL)
|
||||
begin_iter = g_sequence_get_begin_iter (cache->sorted_by_line);
|
||||
|
||||
iter = begin_iter;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
GtkTextLineDisplay *display = g_sequence_get (iter);
|
||||
GSequenceIter *next = g_sequence_iter_next (iter);
|
||||
|
||||
gtk_text_line_display_cache_invalidate_display (cache, display, cursors_only);
|
||||
|
||||
if (iter == end_iter)
|
||||
break;
|
||||
|
||||
iter = next;
|
||||
}
|
||||
}
|
||||
|
||||
static GSequenceIter *
|
||||
find_iter_at_at_y (GtkTextLineDisplayCache *cache,
|
||||
GtkTextLayout *layout,
|
||||
gint y)
|
||||
{
|
||||
GtkTextBTree *btree;
|
||||
GSequenceIter *left;
|
||||
GSequenceIter *right;
|
||||
GSequenceIter *mid;
|
||||
GSequenceIter *end;
|
||||
|
||||
g_assert (cache != NULL);
|
||||
g_assert (layout != NULL);
|
||||
|
||||
if (g_sequence_is_empty (cache->sorted_by_line))
|
||||
return NULL;
|
||||
|
||||
btree = _gtk_text_buffer_get_btree (layout->buffer);
|
||||
|
||||
/* Get some iters so we can work with pointer compare */
|
||||
end = g_sequence_get_end_iter (cache->sorted_by_line);
|
||||
left = g_sequence_get_begin_iter (cache->sorted_by_line);
|
||||
right = g_sequence_iter_prev (end);
|
||||
|
||||
/* We already checked for empty above */
|
||||
g_assert (!g_sequence_iter_is_end (left));
|
||||
g_assert (!g_sequence_iter_is_end (right));
|
||||
|
||||
for (;;)
|
||||
{
|
||||
GtkTextLineDisplay *display;
|
||||
gint cache_y;
|
||||
gint cache_height;
|
||||
|
||||
if (left == right)
|
||||
mid = left;
|
||||
else
|
||||
mid = g_sequence_range_get_midpoint (left, right);
|
||||
|
||||
g_assert (mid != NULL);
|
||||
g_assert (!g_sequence_iter_is_end (mid));
|
||||
|
||||
if (mid == end)
|
||||
break;
|
||||
|
||||
display = g_sequence_get (mid);
|
||||
|
||||
g_assert (display != NULL);
|
||||
g_assert (display->line != NULL);
|
||||
|
||||
cache_y = _gtk_text_btree_find_line_top (btree, display->line, layout);
|
||||
cache_height = display->height;
|
||||
|
||||
if (y >= cache_y && y <= (cache_y + cache_height))
|
||||
return mid;
|
||||
|
||||
if (left == right)
|
||||
break;
|
||||
|
||||
if (y < cache_y)
|
||||
right = mid;
|
||||
else if (y > (cache_y + cache_height))
|
||||
left = g_sequence_iter_next (mid);
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* gtk_text_line_display_cache_invalidate_y_range:
|
||||
* @cache: a GtkTextLineDisplayCache
|
||||
* @y: the starting Y position
|
||||
* @old_height: the height to invalidate
|
||||
* @cursors_only: if only cursors should be invalidated
|
||||
*
|
||||
* Remove all GtkTextLineDisplay that fall into the range starting
|
||||
* from the Y position to Y+Height.
|
||||
*/
|
||||
void
|
||||
gtk_text_line_display_cache_invalidate_y_range (GtkTextLineDisplayCache *cache,
|
||||
GtkTextLayout *layout,
|
||||
gint y,
|
||||
gint old_height,
|
||||
gboolean cursors_only)
|
||||
{
|
||||
GSequenceIter *iter;
|
||||
GtkTextBTree *btree;
|
||||
|
||||
g_assert (cache != NULL);
|
||||
g_assert (layout != NULL);
|
||||
|
||||
STAT_INC (cache->inval_by_y_range);
|
||||
|
||||
btree = _gtk_text_buffer_get_btree (layout->buffer);
|
||||
iter = find_iter_at_at_y (cache, layout, y);
|
||||
|
||||
if (iter == NULL)
|
||||
return;
|
||||
|
||||
while (!g_sequence_iter_is_end (iter))
|
||||
{
|
||||
GtkTextLineDisplay *display;
|
||||
gint cache_y;
|
||||
gint cache_height;
|
||||
|
||||
display = g_sequence_get (iter);
|
||||
iter = g_sequence_iter_next (iter);
|
||||
|
||||
cache_y = _gtk_text_btree_find_line_top (btree, display->line, layout);
|
||||
cache_height = display->height;
|
||||
|
||||
if (cache_y + cache_height > y && cache_y < y + old_height)
|
||||
{
|
||||
gtk_text_line_display_cache_invalidate_display (cache, display, cursors_only);
|
||||
|
||||
y += cache_height;
|
||||
old_height -= cache_height;
|
||||
|
||||
if (old_height > 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gtk_text_line_display_cache_set_cursor_line (GtkTextLineDisplayCache *cache,
|
||||
GtkTextLine *cursor_line)
|
||||
{
|
||||
GtkTextLineDisplay *display;
|
||||
|
||||
g_assert (cache != NULL);
|
||||
|
||||
if (cursor_line == cache->cursor_line)
|
||||
return;
|
||||
|
||||
display = g_hash_table_lookup (cache->line_to_display, cache->cursor_line);
|
||||
|
||||
if (display != NULL)
|
||||
gtk_text_line_display_cache_invalidate_display (cache, display, FALSE);
|
||||
|
||||
cache->cursor_line = cursor_line;
|
||||
|
||||
display = g_hash_table_lookup (cache->line_to_display, cache->cursor_line);
|
||||
|
||||
if (display != NULL)
|
||||
gtk_text_line_display_cache_invalidate_display (cache, display, FALSE);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
* Copyright (C) 2019 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_TEXT_LINE_DISPLAY_CACHE_PRIVATE_H__
|
||||
#define __GTK_TEXT_LINE_DISPLAY_CACHE_PRIVATE_H__
|
||||
|
||||
#include "gtktextlayoutprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GtkTextLineDisplayCache GtkTextLineDisplayCache;
|
||||
|
||||
GtkTextLineDisplayCache *gtk_text_line_display_cache_new (void);
|
||||
void gtk_text_line_display_cache_free (GtkTextLineDisplayCache *cache);
|
||||
GtkTextLineDisplay *gtk_text_line_display_cache_get (GtkTextLineDisplayCache *cache,
|
||||
GtkTextLayout *layout,
|
||||
GtkTextLine *line,
|
||||
gboolean size_only);
|
||||
void gtk_text_line_display_cache_delay_eviction (GtkTextLineDisplayCache *cache);
|
||||
void gtk_text_line_display_cache_set_cursor_line (GtkTextLineDisplayCache *cache,
|
||||
GtkTextLine *line);
|
||||
void gtk_text_line_display_cache_invalidate (GtkTextLineDisplayCache *cache);
|
||||
void gtk_text_line_display_cache_invalidate_cursors (GtkTextLineDisplayCache *cache,
|
||||
GtkTextLine *line);
|
||||
void gtk_text_line_display_cache_invalidate_display (GtkTextLineDisplayCache *cache,
|
||||
GtkTextLineDisplay *display,
|
||||
gboolean cursors_only);
|
||||
void gtk_text_line_display_cache_invalidate_line (GtkTextLineDisplayCache *cache,
|
||||
GtkTextLine *line);
|
||||
void gtk_text_line_display_cache_invalidate_range (GtkTextLineDisplayCache *cache,
|
||||
GtkTextLayout *layout,
|
||||
const GtkTextIter *begin,
|
||||
const GtkTextIter *end,
|
||||
gboolean cursors_only);
|
||||
void gtk_text_line_display_cache_invalidate_y_range (GtkTextLineDisplayCache *cache,
|
||||
GtkTextLayout *layout,
|
||||
gint y,
|
||||
gint height,
|
||||
gboolean cursors_only);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_TEXT_LINE_DISPLAY_CACHE_PRIVATE_H__ */
|
||||
@@ -150,7 +150,6 @@ struct _GtkTextLineSegment {
|
||||
};
|
||||
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkTextLineSegment *gtk_text_line_segment_split (const GtkTextIter *iter);
|
||||
|
||||
GtkTextLineSegment *_gtk_char_segment_new (const gchar *text,
|
||||
|
||||
+2
-2
@@ -27,8 +27,8 @@
|
||||
#include "gtktextview.h"
|
||||
#include "gtktextutil.h"
|
||||
|
||||
#include "gtktextdisplayprivate.h"
|
||||
#include "gtktextbuffer.h"
|
||||
#include "gtktextlayoutprivate.h"
|
||||
#include "gtkmenuitem.h"
|
||||
#include "gtkintl.h"
|
||||
|
||||
@@ -335,7 +335,7 @@ gtk_text_util_create_rich_drag_icon (GtkWidget *widget,
|
||||
|
||||
snapshot = gtk_snapshot_new ();
|
||||
|
||||
gtk_text_layout_snapshot (layout, widget, snapshot, &(GdkRectangle) { 0, 0, layout_width, layout_height });
|
||||
gtk_text_layout_snapshot (layout, widget, snapshot, &(GdkRectangle) { 0, 0, layout_width, layout_height }, 1.0);
|
||||
|
||||
g_object_unref (layout);
|
||||
g_object_unref (new_buffer);
|
||||
|
||||
+124
-88
@@ -41,7 +41,6 @@
|
||||
#include "gtkrenderbackgroundprivate.h"
|
||||
#include "gtkseparatormenuitem.h"
|
||||
#include "gtksettings.h"
|
||||
#include "gtktextdisplayprivate.h"
|
||||
#include "gtktextiterprivate.h"
|
||||
#include "gtkimmulticontext.h"
|
||||
#include "gtkprivate.h"
|
||||
@@ -210,7 +209,10 @@ struct _GtkTextViewPrivate
|
||||
GtkTextMark *first_para_mark; /* Mark at the beginning of the first onscreen paragraph */
|
||||
gint first_para_pixels; /* Offset of top of screen in the first onscreen paragraph */
|
||||
|
||||
guint blink_timeout;
|
||||
guint64 blink_start_time;
|
||||
guint blink_tick;
|
||||
float cursor_alpha;
|
||||
|
||||
guint scroll_timeout;
|
||||
|
||||
guint first_validate_idle; /* Idle to revalidate onscreen portion, runs before resize */
|
||||
@@ -4571,11 +4573,15 @@ gtk_text_view_style_updated (GtkWidget *widget)
|
||||
style_context = gtk_widget_get_style_context (widget);
|
||||
change = gtk_style_context_get_change (style_context);
|
||||
|
||||
if ((change == NULL || gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_TEXT)) &&
|
||||
if ((change == NULL ||
|
||||
gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_TEXT |
|
||||
GTK_CSS_AFFECTS_BACKGROUND |
|
||||
GTK_CSS_AFFECTS_CONTENT)) &&
|
||||
priv->layout && priv->layout->default_style)
|
||||
{
|
||||
gtk_text_view_set_attributes_from_style (text_view,
|
||||
priv->layout->default_style);
|
||||
gtk_text_layout_default_style_changed (priv->layout);
|
||||
|
||||
ltr_context = gtk_widget_create_pango_context (widget);
|
||||
pango_context_set_base_dir (ltr_context, PANGO_DIRECTION_LTR);
|
||||
@@ -5347,12 +5353,6 @@ gtk_text_view_paint (GtkWidget *widget,
|
||||
g_warning (G_STRLOC ": somehow some text lines were modified or scrolling occurred since the last validation of lines on the screen - may be a text widget bug.");
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf ("painting %d,%d %d x %d\n",
|
||||
area->x, area->y,
|
||||
area->width, area->height);
|
||||
#endif
|
||||
|
||||
gtk_snapshot_save (snapshot);
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (-priv->xoffset, -priv->yoffset));
|
||||
@@ -5365,7 +5365,8 @@ gtk_text_view_paint (GtkWidget *widget,
|
||||
priv->yoffset,
|
||||
gtk_widget_get_width (widget),
|
||||
gtk_widget_get_height (widget)
|
||||
});
|
||||
},
|
||||
priv->cursor_alpha);
|
||||
|
||||
gtk_snapshot_restore (snapshot);
|
||||
}
|
||||
@@ -5662,23 +5663,88 @@ get_cursor_blink_timeout (GtkTextView *text_view)
|
||||
* Blink!
|
||||
*/
|
||||
|
||||
static gint
|
||||
blink_cb (gpointer data)
|
||||
{
|
||||
GtkTextView *text_view;
|
||||
GtkTextViewPrivate *priv;
|
||||
gboolean visible;
|
||||
gint blink_timeout;
|
||||
typedef struct {
|
||||
guint64 start;
|
||||
guint64 end;
|
||||
} BlinkData;
|
||||
|
||||
text_view = GTK_TEXT_VIEW (data);
|
||||
priv = text_view->priv;
|
||||
static gboolean blink_cb (GtkWidget *widget,
|
||||
GdkFrameClock *clock,
|
||||
gpointer user_data);
|
||||
|
||||
|
||||
static void
|
||||
add_blink_timeout (GtkTextView *self,
|
||||
gboolean delay)
|
||||
{
|
||||
GtkTextViewPrivate *priv = self->priv;
|
||||
BlinkData *data;
|
||||
int blink_time;
|
||||
|
||||
priv->blink_start_time = g_get_monotonic_time ();
|
||||
priv->cursor_alpha = 1.0;
|
||||
|
||||
blink_time = get_cursor_time (self);
|
||||
|
||||
data = g_new (BlinkData, 1);
|
||||
data->start = priv->blink_start_time;
|
||||
if (delay)
|
||||
data->start += blink_time * 1000 / 2;
|
||||
data->end = data->start + blink_time * 1000;
|
||||
|
||||
priv->blink_tick = gtk_widget_add_tick_callback (GTK_WIDGET (self),
|
||||
blink_cb,
|
||||
data,
|
||||
g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
remove_blink_timeout (GtkTextView *self)
|
||||
{
|
||||
GtkTextViewPrivate *priv = self->priv;
|
||||
|
||||
if (priv->blink_tick)
|
||||
{
|
||||
gtk_widget_remove_tick_callback (GTK_WIDGET (self), priv->blink_tick);
|
||||
priv->blink_tick = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static float
|
||||
blink_alpha (float phase)
|
||||
{
|
||||
/* keep it simple, and split the blink cycle evenly
|
||||
* into visible, fading out, invisible, fading in
|
||||
*/
|
||||
if (phase < 0.25)
|
||||
return 1;
|
||||
else if (phase < 0.5)
|
||||
return 1 - 4 * (phase - 0.25);
|
||||
else if (phase < 0.75)
|
||||
return 0;
|
||||
else
|
||||
return 4 * (phase - 0.75);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
blink_cb (GtkWidget *widget,
|
||||
GdkFrameClock *clock,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkTextView *text_view = GTK_TEXT_VIEW (widget);
|
||||
GtkTextViewPrivate *priv = text_view->priv;
|
||||
BlinkData *data = user_data;
|
||||
gint blink_timeout;
|
||||
gint blink_time;
|
||||
guint64 now;
|
||||
float phase;
|
||||
float alpha;
|
||||
|
||||
if (!gtk_widget_has_focus (GTK_WIDGET (text_view)))
|
||||
{
|
||||
g_warning ("GtkTextView - did not receive a focus-out.\n"
|
||||
"If you handle this event, you must return\n"
|
||||
"GDK_EVENT_PROPAGATE so the text view gets the event as well");
|
||||
|
||||
gtk_text_view_check_cursor_blink (text_view);
|
||||
|
||||
return FALSE;
|
||||
@@ -5687,47 +5753,45 @@ blink_cb (gpointer data)
|
||||
g_assert (priv->layout);
|
||||
g_assert (cursor_visible (text_view));
|
||||
|
||||
visible = gtk_text_layout_get_cursor_visible (priv->layout);
|
||||
|
||||
blink_timeout = get_cursor_blink_timeout (text_view);
|
||||
if (priv->blink_time > 1000 * blink_timeout &&
|
||||
blink_timeout < G_MAXINT/1000)
|
||||
blink_time = get_cursor_time (text_view);
|
||||
|
||||
now = g_get_monotonic_time ();
|
||||
|
||||
if (now > priv->blink_start_time + blink_timeout * 1000000)
|
||||
{
|
||||
/* we've blinked enough without the user doing anything, stop blinking */
|
||||
visible = 0;
|
||||
priv->blink_timeout = 0;
|
||||
}
|
||||
else if (visible)
|
||||
{
|
||||
priv->blink_timeout = g_timeout_add (get_cursor_time (text_view) * CURSOR_OFF_MULTIPLIER / CURSOR_DIVIDER,
|
||||
blink_cb,
|
||||
text_view);
|
||||
g_source_set_name_by_id (priv->blink_timeout, "[gtk] blink_cb");
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->blink_timeout = g_timeout_add (get_cursor_time (text_view) * CURSOR_ON_MULTIPLIER / CURSOR_DIVIDER,
|
||||
blink_cb,
|
||||
text_view);
|
||||
g_source_set_name_by_id (priv->blink_timeout, "[gtk] blink_cb");
|
||||
priv->blink_time += get_cursor_time (text_view);
|
||||
priv->cursor_alpha = 1.0;
|
||||
remove_blink_timeout (text_view);
|
||||
gtk_widget_queue_draw (widget);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
gtk_text_layout_set_cursor_visible (priv->layout, !visible);
|
||||
phase = (now - data->start) / (float) (data->end - data->start);
|
||||
|
||||
/* Remove ourselves */
|
||||
return FALSE;
|
||||
if (now >= data->end)
|
||||
{
|
||||
data->start = data->end;
|
||||
data->end = data->start + blink_time * 1000;
|
||||
}
|
||||
|
||||
alpha = blink_alpha (phase);
|
||||
|
||||
if (priv->cursor_alpha != alpha)
|
||||
{
|
||||
priv->cursor_alpha = alpha;
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gtk_text_view_stop_cursor_blink (GtkTextView *text_view)
|
||||
{
|
||||
if (text_view->priv->blink_timeout)
|
||||
{
|
||||
g_source_remove (text_view->priv->blink_timeout);
|
||||
text_view->priv->blink_timeout = 0;
|
||||
}
|
||||
remove_blink_timeout (text_view);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -5735,52 +5799,25 @@ gtk_text_view_check_cursor_blink (GtkTextView *text_view)
|
||||
{
|
||||
GtkTextViewPrivate *priv = text_view->priv;
|
||||
|
||||
if (priv->layout != NULL &&
|
||||
cursor_visible (text_view) &&
|
||||
gtk_widget_has_focus (GTK_WIDGET (text_view)))
|
||||
if (cursor_blinks (text_view))
|
||||
{
|
||||
if (cursor_blinks (text_view))
|
||||
{
|
||||
if (priv->blink_timeout == 0)
|
||||
{
|
||||
gtk_text_layout_set_cursor_visible (priv->layout, TRUE);
|
||||
|
||||
priv->blink_timeout = g_timeout_add (get_cursor_time (text_view) * CURSOR_OFF_MULTIPLIER / CURSOR_DIVIDER,
|
||||
blink_cb,
|
||||
text_view);
|
||||
g_source_set_name_by_id (priv->blink_timeout, "[gtk] blink_cb");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_text_view_stop_cursor_blink (text_view);
|
||||
gtk_text_layout_set_cursor_visible (priv->layout, TRUE);
|
||||
}
|
||||
if (!priv->blink_tick)
|
||||
add_blink_timeout (text_view, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_text_view_stop_cursor_blink (text_view);
|
||||
gtk_text_layout_set_cursor_visible (priv->layout, FALSE);
|
||||
if (priv->blink_tick)
|
||||
remove_blink_timeout (text_view);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_view_pend_cursor_blink (GtkTextView *text_view)
|
||||
{
|
||||
GtkTextViewPrivate *priv = text_view->priv;
|
||||
|
||||
if (priv->layout != NULL &&
|
||||
cursor_visible (text_view) &&
|
||||
gtk_widget_has_focus (GTK_WIDGET (text_view)) &&
|
||||
cursor_blinks (text_view))
|
||||
if (cursor_blinks (text_view))
|
||||
{
|
||||
gtk_text_view_stop_cursor_blink (text_view);
|
||||
gtk_text_layout_set_cursor_visible (priv->layout, TRUE);
|
||||
|
||||
priv->blink_timeout = g_timeout_add (get_cursor_time (text_view) * CURSOR_PEND_MULTIPLIER / CURSOR_DIVIDER,
|
||||
blink_cb,
|
||||
text_view);
|
||||
g_source_set_name_by_id (priv->blink_timeout, "[gtk] blink_cb");
|
||||
remove_blink_timeout (text_view);
|
||||
add_blink_timeout (text_view, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5789,7 +5826,7 @@ gtk_text_view_reset_blink_time (GtkTextView *text_view)
|
||||
{
|
||||
GtkTextViewPrivate *priv = text_view->priv;
|
||||
|
||||
priv->blink_time = 0;
|
||||
priv->blink_start_time = g_get_monotonic_time ();
|
||||
}
|
||||
|
||||
|
||||
@@ -8218,6 +8255,8 @@ gtk_text_view_commit_handler (GtkIMContext *context,
|
||||
GtkTextView *text_view)
|
||||
{
|
||||
gtk_text_view_commit_text (text_view, str);
|
||||
gtk_text_view_reset_blink_time (text_view);
|
||||
gtk_text_view_pend_cursor_blink (text_view);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -8864,12 +8903,10 @@ append_bubble_item (GtkTextView *text_view,
|
||||
item = gtk_button_new ();
|
||||
gtk_widget_set_focus_on_click (item, FALSE);
|
||||
image = gtk_image_new_from_icon_name (icon_name);
|
||||
gtk_widget_show (image);
|
||||
gtk_container_add (GTK_CONTAINER (item), image);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (item), "image-button");
|
||||
gtk_actionable_set_action_name (GTK_ACTIONABLE (item), action_name);
|
||||
|
||||
gtk_widget_show (GTK_WIDGET (item));
|
||||
gtk_container_add (GTK_CONTAINER (toolbar), item);
|
||||
}
|
||||
|
||||
@@ -8900,7 +8937,6 @@ gtk_text_view_selection_bubble_popup_show (gpointer user_data)
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
||||
g_object_set (box, "margin", 10, NULL);
|
||||
gtk_widget_show (box);
|
||||
toolbar = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (toolbar), "linked");
|
||||
gtk_container_add (GTK_CONTAINER (priv->selection_bubble), box);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,94 @@
|
||||
/* gtktimingfunction.h: Timing functions for animations
|
||||
*
|
||||
* Copyright 2019 GNOME Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtktypes.h>
|
||||
#include <gtk/gtkenums.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_TIMING_FUNCTION (gtk_timing_function_get_type())
|
||||
|
||||
/**
|
||||
* GtkTimingFunction:
|
||||
*
|
||||
* An opaque type representing a timing, or "easing" function.
|
||||
*/
|
||||
typedef struct _GtkTimingFunction GtkTimingFunction;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gtk_timing_function_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_timing_function_equal (GtkTimingFunction *a,
|
||||
GtkTimingFunction *b);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkTimingFunction * gtk_timing_function_ref (GtkTimingFunction *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_timing_function_unref (GtkTimingFunction *self);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
char * gtk_timing_function_to_string (GtkTimingFunction *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_timing_function_print (GtkTimingFunction *self,
|
||||
GString *buf);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_timing_function_parse (const char *string,
|
||||
GtkTimingFunction **out_func);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
double gtk_timing_function_transform_time (GtkTimingFunction *self,
|
||||
double elapsed,
|
||||
double duration);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_timing_function_get_control_points (GtkTimingFunction *self,
|
||||
double *x_1,
|
||||
double *y_1,
|
||||
double *x_2,
|
||||
double *y_2);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_timing_function_get_steps (GtkTimingFunction *self,
|
||||
int *n_steps,
|
||||
GtkStepPosition *position);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkTimingFunction * gtk_linear (void);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkTimingFunction * gtk_cubic_bezier (double x_1,
|
||||
double y_1,
|
||||
double x_2,
|
||||
double y_2);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkTimingFunction * gtk_ease (void);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkTimingFunction * gtk_ease_in (void);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkTimingFunction * gtk_ease_out (void);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkTimingFunction * gtk_ease_in_out (void);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkTimingFunction * gtk_steps (int n_steps,
|
||||
GtkStepPosition position);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkTimingFunction * gtk_step_start (void);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkTimingFunction * gtk_step_end (void);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -0,0 +1,29 @@
|
||||
/* gtktimingfunctionprivate.h: Private declarations for GtkTimingFunction
|
||||
*
|
||||
* Copyright 2019 GNOME Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "gtktimingfunction.h"
|
||||
#include "gtkcssparserprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
gboolean gtk_timing_function_parser_parse (GtkCssParser *parser,
|
||||
GtkTimingFunction **out_function);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -10107,7 +10107,6 @@ gtk_widget_buildable_finish_layout_properties (GtkWidget *widget,
|
||||
}
|
||||
|
||||
g_slist_free_full (layout_properties, layout_property_info_free);
|
||||
g_slice_free (LayoutParserData, layout_data);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+33
-28
@@ -283,6 +283,7 @@ typedef struct
|
||||
GList *foci;
|
||||
|
||||
GtkConstraintSolver *constraint_solver;
|
||||
GtkAnimationManager *animation_manager;
|
||||
} GtkWindowPrivate;
|
||||
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
@@ -2367,6 +2368,23 @@ gtk_window_root_get_constraint_solver (GtkRoot *root)
|
||||
return priv->constraint_solver;
|
||||
}
|
||||
|
||||
static GtkAnimationManager *
|
||||
gtk_window_root_get_animation_manager (GtkRoot *root)
|
||||
{
|
||||
GtkWindow *self = GTK_WINDOW (root);
|
||||
GtkWindowPrivate *priv = gtk_window_get_instance_private (self);
|
||||
GdkFrameClock *frame_clock;
|
||||
|
||||
if (priv->animation_manager == NULL)
|
||||
priv->animation_manager = gtk_animation_manager_new ();
|
||||
|
||||
frame_clock = gtk_widget_get_frame_clock (GTK_WIDGET (self));
|
||||
if (frame_clock != NULL)
|
||||
gtk_animation_manager_set_frame_clock (priv->animation_manager, frame_clock);
|
||||
|
||||
return priv->animation_manager;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_window_native_get_surface_transform (GtkNative *native,
|
||||
int *x,
|
||||
@@ -2396,6 +2414,7 @@ gtk_window_root_interface_init (GtkRootInterface *iface)
|
||||
{
|
||||
iface->get_display = gtk_window_root_get_display;
|
||||
iface->get_constraint_solver = gtk_window_root_get_constraint_solver;
|
||||
iface->get_animation_manager = gtk_window_root_get_animation_manager;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -4738,6 +4757,7 @@ gtk_window_finalize (GObject *object)
|
||||
priv->mnemonics_display_timeout_id = 0;
|
||||
}
|
||||
|
||||
g_clear_object (&priv->animation_manager);
|
||||
g_clear_object (&priv->constraint_solver);
|
||||
g_clear_object (&priv->renderer);
|
||||
|
||||
@@ -8087,9 +8107,10 @@ gtk_window_set_display (GtkWindow *window,
|
||||
"notify::gtk-application-prefer-dark-theme",
|
||||
G_CALLBACK (gtk_window_on_theme_variant_changed), window);
|
||||
#endif
|
||||
priv->display = display;
|
||||
|
||||
gtk_widget_unroot (widget);
|
||||
priv->display = display;
|
||||
|
||||
gtk_widget_root (widget);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (window), window_props[PROP_DISPLAY]);
|
||||
@@ -9233,30 +9254,6 @@ gtk_window_unexport_handle (GtkWindow *window)
|
||||
G_OBJECT_TYPE_NAME (priv->surface));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_window_add_pointer_focus (GtkWindow *window,
|
||||
GtkPointerFocus *focus)
|
||||
{
|
||||
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
|
||||
|
||||
priv->foci = g_list_prepend (priv->foci, gtk_pointer_focus_ref (focus));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_window_remove_pointer_focus (GtkWindow *window,
|
||||
GtkPointerFocus *focus)
|
||||
{
|
||||
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
|
||||
GList *pos;
|
||||
|
||||
pos = g_list_find (priv->foci, focus);
|
||||
if (!pos)
|
||||
return;
|
||||
|
||||
priv->foci = g_list_remove (priv->foci, focus);
|
||||
gtk_pointer_focus_unref (focus);
|
||||
}
|
||||
|
||||
static GtkPointerFocus *
|
||||
gtk_window_lookup_pointer_focus (GtkWindow *window,
|
||||
GdkDevice *device,
|
||||
@@ -9317,6 +9314,7 @@ gtk_window_update_pointer_focus (GtkWindow *window,
|
||||
gdouble x,
|
||||
gdouble y)
|
||||
{
|
||||
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
|
||||
GtkPointerFocus *focus;
|
||||
|
||||
focus = gtk_window_lookup_pointer_focus (window, device, sequence);
|
||||
@@ -9331,7 +9329,14 @@ gtk_window_update_pointer_focus (GtkWindow *window,
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_window_remove_pointer_focus (window, focus);
|
||||
GList *pos;
|
||||
|
||||
pos = g_list_find (priv->foci, focus);
|
||||
if (pos)
|
||||
{
|
||||
priv->foci = g_list_remove (priv->foci, focus);
|
||||
gtk_pointer_focus_unref (focus);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_pointer_focus_unref (focus);
|
||||
@@ -9339,8 +9344,7 @@ gtk_window_update_pointer_focus (GtkWindow *window,
|
||||
else if (target)
|
||||
{
|
||||
focus = gtk_pointer_focus_new (window, target, device, sequence, x, y);
|
||||
gtk_window_add_pointer_focus (window, focus);
|
||||
gtk_pointer_focus_unref (focus);
|
||||
priv->foci = g_list_prepend (priv->foci, focus);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9371,6 +9375,7 @@ gtk_window_update_pointer_focus_on_state_change (GtkWindow *window,
|
||||
/* Unmapping the toplevel, remove pointer focus */
|
||||
priv->foci = g_list_remove_link (priv->foci, cur);
|
||||
gtk_pointer_focus_unref (focus);
|
||||
g_list_free (cur);
|
||||
}
|
||||
else if (focus->target == widget ||
|
||||
gtk_widget_is_ancestor (focus->target, widget))
|
||||
|
||||
@@ -71,6 +71,7 @@ struct _GtkInspectorGeneralPrivate
|
||||
GtkWidget *gtk_version;
|
||||
GtkWidget *gdk_backend;
|
||||
GtkWidget *gsk_renderer;
|
||||
GtkWidget *pango_fontmap;
|
||||
GtkWidget *gl_version;
|
||||
GtkWidget *gl_vendor;
|
||||
GtkWidget *vk_device;
|
||||
@@ -625,6 +626,27 @@ init_display (GtkInspectorGeneral *gen)
|
||||
populate_display (display, gen);
|
||||
}
|
||||
|
||||
static void
|
||||
init_pango (GtkInspectorGeneral *gen)
|
||||
{
|
||||
PangoFontMap *fontmap;
|
||||
const char *type;
|
||||
const char *name;
|
||||
|
||||
fontmap = pango_cairo_font_map_get_default ();
|
||||
type = G_OBJECT_TYPE_NAME (fontmap);
|
||||
if (strcmp (type, "PangoCairoFcFontMap") == 0)
|
||||
name = "fontconfig";
|
||||
else if (strcmp (type, "PangoCairoCoreTextFontMap") == 0)
|
||||
name = "coretext";
|
||||
else if (strcmp (type, "PangoCairoWin32FontMap") == 0)
|
||||
name = "win32";
|
||||
else
|
||||
name = type;
|
||||
|
||||
gtk_label_set_label (GTK_LABEL (gen->priv->pango_fontmap), name);
|
||||
}
|
||||
|
||||
static void populate_seats (GtkInspectorGeneral *gen);
|
||||
|
||||
static void
|
||||
@@ -793,6 +815,7 @@ gtk_inspector_general_init (GtkInspectorGeneral *gen)
|
||||
init_version (gen);
|
||||
init_env (gen);
|
||||
init_display (gen);
|
||||
init_pango (gen);
|
||||
init_gl (gen);
|
||||
init_vulkan (gen);
|
||||
init_device (gen);
|
||||
@@ -924,6 +947,7 @@ gtk_inspector_general_class_init (GtkInspectorGeneralClass *klass)
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, gtk_version);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, gdk_backend);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, gsk_renderer);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, pango_fontmap);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, gl_version);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, gl_vendor);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, vk_device);
|
||||
|
||||
@@ -96,6 +96,33 @@
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="activatable">0</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="margin">10</property>
|
||||
<property name="spacing">40</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="pango_fontmap_label">
|
||||
<property name="label" translatable="yes">Pango Fontmap</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">baseline</property>
|
||||
<property name="xalign">0.0</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="pango_fontmap">
|
||||
<property name="selectable">1</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">baseline</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -578,6 +605,7 @@
|
||||
<widget name="gtk_version_label"/>
|
||||
<widget name="gdk_backend_label"/>
|
||||
<widget name="gsk_renderer_label"/>
|
||||
<widget name="pango_fontmap_label"/>
|
||||
<widget name="gl_version_label"/>
|
||||
<widget name="gl_vendor_label"/>
|
||||
<widget name="vk_device_label"/>
|
||||
|
||||
+5
-2
@@ -23,6 +23,7 @@ gtk_private_sources = files([
|
||||
'gtkactionobservable.c',
|
||||
'gtkactionobserver.c',
|
||||
'gtkallocatedbitmask.c',
|
||||
'gtkanimationmanager.c',
|
||||
'gtkapplicationaccels.c',
|
||||
'gtkapplicationimpl.c',
|
||||
'gtkbookmarksmanager.c',
|
||||
@@ -315,7 +316,6 @@ gtk_public_sources = files([
|
||||
'gtkradiomenuitem.c',
|
||||
'gtkradiotoolbutton.c',
|
||||
'gtkrange.c',
|
||||
'gtktreerbtree.c',
|
||||
'gtkrecentmanager.c',
|
||||
'gtkrender.c',
|
||||
'gtkrenderbackground.c',
|
||||
@@ -366,10 +366,10 @@ gtk_public_sources = files([
|
||||
'gtktextattributes.c',
|
||||
'gtktextbuffer.c',
|
||||
'gtktextchild.c',
|
||||
'gtktextdisplay.c',
|
||||
'gtktexthandle.c',
|
||||
'gtktextiter.c',
|
||||
'gtktextlayout.c',
|
||||
'gtktextlinedisplaycache.c',
|
||||
'gtktextmark.c',
|
||||
'gtktextsegment.c',
|
||||
'gtktexttag.c',
|
||||
@@ -377,6 +377,7 @@ gtk_public_sources = files([
|
||||
'gtktexttypes.c',
|
||||
'gtktextutil.c',
|
||||
'gtktextview.c',
|
||||
'gtktimingfunction.c',
|
||||
'gtktogglebutton.c',
|
||||
'gtktoggletoolbutton.c',
|
||||
'gtktoolbar.c',
|
||||
@@ -391,6 +392,7 @@ gtk_public_sources = files([
|
||||
'gtktreemodel.c',
|
||||
'gtktreemodelfilter.c',
|
||||
'gtktreemodelsort.c',
|
||||
'gtktreerbtree.c',
|
||||
'gtktreeselection.c',
|
||||
'gtktreesortable.c',
|
||||
'gtktreestore.c',
|
||||
@@ -618,6 +620,7 @@ gtk_public_headers = files([
|
||||
'gtktexttag.h',
|
||||
'gtktexttagtable.h',
|
||||
'gtktextview.h',
|
||||
'gtktimingfunction.h',
|
||||
'gtktogglebutton.h',
|
||||
'gtktoggletoolbutton.h',
|
||||
'gtktoolbar.h',
|
||||
|
||||
@@ -315,6 +315,10 @@ entry {
|
||||
@extend .dim-label;
|
||||
}
|
||||
|
||||
block-cursor {
|
||||
@include entry(block_cursor);
|
||||
}
|
||||
|
||||
&.flat {
|
||||
&:focus, &:backdrop, &:disabled, &:backdrop:disabled, & {
|
||||
min-height: 0;
|
||||
@@ -3986,7 +3990,7 @@ row image.sidebar-icon { opacity: $_placesidebar_icons_opacity; } // dim the sid
|
||||
// on this oddity
|
||||
|
||||
placessidebar {
|
||||
> viewport.frame { border-style: none; }
|
||||
> scrolledwindow.frame { border-style: none; }
|
||||
|
||||
row {
|
||||
// Needs overriding of the GtkListBoxRow padding
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
// use the default one
|
||||
//
|
||||
// possible $t values:
|
||||
// normal, focus, insensitive, backdrop, backdrop-insensitive, osd, osd-focus, osd-backdrop;
|
||||
// normal, focus, insensitive, backdrop, backdrop-insensitive, osd, osd-focus, osd-backdrop, block_cursor;
|
||||
//
|
||||
|
||||
$_blank_edge: if($edge == none, none, 0 1px transparentize($edge, 1));
|
||||
@@ -111,6 +111,10 @@
|
||||
text-shadow: none;
|
||||
-gtk-icon-shadow: none;
|
||||
}
|
||||
@if $t==block_cursor {
|
||||
color: $base_color;
|
||||
background-color: $text_color;
|
||||
}
|
||||
}
|
||||
|
||||
// buttons
|
||||
|
||||
+2
-1
@@ -12,5 +12,6 @@ Description: GTK Graphical UI Library
|
||||
Version: @VERSION@
|
||||
Requires: @GDK_PACKAGES@ @GSK_PACKAGES@ @GTK_PACKAGES@
|
||||
Requires.private: @GDK_PRIVATE_PACKAGES@ @GSK_PRIVATE_PACKAGES@ @GTK_PRIVATE_PACKAGES@
|
||||
Libs: -L${libdir} -lgtk-4 @GDK_EXTRA_LIBS@ @GSK_EXTRA_LIBS@ @GTK_EXTRA_LIBS@
|
||||
Libs: -L${libdir} -lgtk-4
|
||||
Libs.private: @GDK_EXTRA_LIBS@ @GSK_EXTRA_LIBS@ @GTK_EXTRA_LIBS@
|
||||
Cflags: -I${includedir}/gtk-@GTK_API_VERSION@ @GDK_EXTRA_CFLAGS@ @GSK_EXTRA_CFLAGS@ @GTK_EXTRA_CFLAGS@
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ atk_req = '>= 2.15.1'
|
||||
cairo_req = '>= 1.14.0'
|
||||
gdk_pixbuf_req = '>= 2.30.0'
|
||||
introspection_req = '>= 1.39.0'
|
||||
wayland_proto_req = '>= 1.12'
|
||||
wayland_proto_req = '>= 1.14'
|
||||
wayland_req = '>= 1.14.91'
|
||||
graphene_req = '>= 1.9.1'
|
||||
epoxy_req = '>= 1.4'
|
||||
|
||||
@@ -284,7 +284,6 @@ gtk/gtkswitch.c
|
||||
gtk/gtktextbuffer.c
|
||||
gtk/gtktext.c
|
||||
gtk/gtktextchild.c
|
||||
gtk/gtktextdisplay.c
|
||||
gtk/gtktexthandle.c
|
||||
gtk/gtktextiter.c
|
||||
gtk/gtktextlayout.c
|
||||
|
||||
@@ -19,6 +19,7 @@ demos/gtk-demo/filtermodel.ui
|
||||
demos/gtk-demo/fishbowl.ui
|
||||
demos/gtk-demo/font_features.c
|
||||
demos/gtk-demo/font-features.ui
|
||||
demos/gtk-demo/fontrendering.ui
|
||||
demos/gtk-demo/iconview.c
|
||||
demos/gtk-demo/infobar.c
|
||||
demos/gtk-demo/listbox.ui
|
||||
|
||||
+3
-3
@@ -370,15 +370,15 @@ msgstr "L'etiqueta de l'enllaç al lloc web del programa"
|
||||
|
||||
#: gtk/gtkaboutdialog.c:501
|
||||
msgid "Authors"
|
||||
msgstr "Autors"
|
||||
msgstr "Autoria"
|
||||
|
||||
#: gtk/gtkaboutdialog.c:502
|
||||
msgid "List of authors of the program"
|
||||
msgstr "Llista d'autors del programa"
|
||||
msgstr "Autoria del programa"
|
||||
|
||||
#: gtk/gtkaboutdialog.c:515
|
||||
msgid "Documenters"
|
||||
msgstr "Documentadors"
|
||||
msgstr "Equip de documentació"
|
||||
|
||||
#: gtk/gtkaboutdialog.c:516
|
||||
msgid "List of people documenting the program"
|
||||
|
||||
+97
-97
@@ -8,8 +8,8 @@
|
||||
msgid ""
|
||||
msgstr "Project-Id-Version: gtk+_properties master\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2019-07-08 07:11+0000\n"
|
||||
"PO-Revision-Date: 2019-04-26 19:00+0100\n"
|
||||
"POT-Creation-Date: 2019-07-18 19:33+0000\n"
|
||||
"PO-Revision-Date: 2019-07-21 10:00+0100\n"
|
||||
"Last-Translator: Asier Sarasua Garmendia <asier.sarasua@gmail.com>\n"
|
||||
"Language-Team: Basque <librezale@librezale.eus>\n"
|
||||
"Language: eu\n"
|
||||
@@ -193,7 +193,7 @@ msgid "The GL context this context shares data with"
|
||||
msgstr "GL-ren testuingurua (testuinguruko datuak partekatu dituenak)"
|
||||
|
||||
#
|
||||
#: gdk/gdksurface.c:424 gdk/gdksurface.c:425 gtk/gtkwidget.c:1067
|
||||
#: gdk/gdksurface.c:424 gdk/gdksurface.c:425 gtk/gtkwidget.c:1069
|
||||
msgid "Cursor"
|
||||
msgstr "Kurtsorea"
|
||||
|
||||
@@ -224,7 +224,7 @@ msgstr "Automatikoki ezkutatu"
|
||||
|
||||
#: gdk/gdksurface.c:473
|
||||
msgid "Whether to dismiss the surface on outside clicks"
|
||||
msgstr ""
|
||||
msgstr "Gainazala baztertuko den ala ez kanpoko kliketan"
|
||||
|
||||
#
|
||||
#: gdk/gdksurface.c:479 gdk/gdksurface.c:480
|
||||
@@ -686,7 +686,7 @@ msgstr "Erakutsi menu-barra"
|
||||
msgid "TRUE if the window should show a menubar at the top of the window"
|
||||
msgstr "TRUE (egia) leihoak goian menu-barra erakutsi behar badu"
|
||||
|
||||
#: gtk/gtkaspectframe.c:120 gtk/gtkwidget.c:1138
|
||||
#: gtk/gtkaspectframe.c:120 gtk/gtkwidget.c:1140
|
||||
msgid "Horizontal Alignment"
|
||||
msgstr "Lerrokadura horizontala"
|
||||
|
||||
@@ -694,7 +694,7 @@ msgstr "Lerrokadura horizontala"
|
||||
msgid "X alignment of the child"
|
||||
msgstr "Umearen X lerrokatzea"
|
||||
|
||||
#: gtk/gtkaspectframe.c:127 gtk/gtkwidget.c:1151
|
||||
#: gtk/gtkaspectframe.c:127 gtk/gtkwidget.c:1153
|
||||
msgid "Vertical Alignment"
|
||||
msgstr "Lerrokatze bertikala"
|
||||
|
||||
@@ -1066,7 +1066,7 @@ msgstr "ikusgai"
|
||||
msgid "Display the cell"
|
||||
msgstr "Bistaratu gelaxka"
|
||||
|
||||
#: gtk/gtkcellrenderer.c:308 gtk/gtkwidget.c:996
|
||||
#: gtk/gtkcellrenderer.c:308 gtk/gtkwidget.c:998
|
||||
msgid "Sensitive"
|
||||
msgstr "Sentikorra"
|
||||
|
||||
@@ -1258,7 +1258,7 @@ msgstr "Progresio-barraren balioa"
|
||||
|
||||
#: gtk/gtkcellrendererprogress.c:166 gtk/gtkcellrenderertext.c:253
|
||||
#: gtk/gtkeditable.c:369 gtk/gtkentrybuffer.c:351 gtk/gtkmessagedialog.c:200
|
||||
#: gtk/gtkmodelbutton.c:1048 gtk/gtkprogressbar.c:227 gtk/gtktextbuffer.c:425
|
||||
#: gtk/gtkmodelbutton.c:1048 gtk/gtkprogressbar.c:213 gtk/gtktextbuffer.c:425
|
||||
msgid "Text"
|
||||
msgstr "Testua"
|
||||
|
||||
@@ -1295,16 +1295,16 @@ msgid "The vertical text alignment, from 0 (top) to 1 (bottom)."
|
||||
msgstr "Lerrokatze bertikala, 0tik (goian) 1era (behean)."
|
||||
|
||||
#: gtk/gtkcellrendererprogress.c:230 gtk/gtklevelbar.c:1060
|
||||
#: gtk/gtkprogressbar.c:204 gtk/gtkrange.c:380
|
||||
#: gtk/gtkprogressbar.c:190 gtk/gtkrange.c:380
|
||||
msgid "Inverted"
|
||||
msgstr "Alderantzikatuta"
|
||||
|
||||
#: gtk/gtkcellrendererprogress.c:231 gtk/gtkprogressbar.c:205
|
||||
#: gtk/gtkcellrendererprogress.c:231 gtk/gtkprogressbar.c:191
|
||||
msgid "Invert the direction in which the progress bar grows"
|
||||
msgstr "Alderantzikatu aurrerapen-barraren hazte-norabidea"
|
||||
|
||||
#: gtk/gtkcellrendererspin.c:131 gtk/gtkrange.c:373 gtk/gtkscalebutton.c:213
|
||||
#: gtk/gtkscrollbar.c:235 gtk/gtkspinbutton.c:379
|
||||
#: gtk/gtkscrollbar.c:198 gtk/gtkspinbutton.c:379
|
||||
msgid "Adjustment"
|
||||
msgstr "Egokitzea"
|
||||
|
||||
@@ -1528,7 +1528,7 @@ msgid ""
|
||||
"probably don’t need it"
|
||||
msgstr "Testu honetako hizkuntza ISOren kode gisa dago. Pango-k laguntza gisa erabil dezake testua bihurtzean. Parametro hori ulertzen ez baduzu, beharbada ez duzu beharko"
|
||||
|
||||
#: gtk/gtkcellrenderertext.c:444 gtk/gtklabel.c:935 gtk/gtkprogressbar.c:266
|
||||
#: gtk/gtkcellrenderertext.c:444 gtk/gtklabel.c:935 gtk/gtkprogressbar.c:252
|
||||
msgid "Ellipsize"
|
||||
msgstr "Elipsi gisa"
|
||||
|
||||
@@ -1880,7 +1880,7 @@ msgstr "Uneko kolorea, GdkRGBA gisa"
|
||||
msgid "Whether alpha should be shown"
|
||||
msgstr "Alfa erakutsi behar den ala ez adierazten du"
|
||||
|
||||
#: gtk/gtkcolorchooserdialog.c:217 gtk/gtkcolorchooserwidget.c:711
|
||||
#: gtk/gtkcolorchooserdialog.c:217 gtk/gtkcolorchooserwidget.c:709
|
||||
msgid "Show editor"
|
||||
msgstr "Erakutsi editorea"
|
||||
|
||||
@@ -2034,7 +2034,7 @@ msgstr "Iturburuko atributua"
|
||||
|
||||
#: gtk/gtkconstraint.c:249
|
||||
msgid "The attribute of the source widget set by the constraint"
|
||||
msgstr ""
|
||||
msgstr "Iturburuko trepetaren atributua, murriztapenak ezarritakoa"
|
||||
|
||||
#
|
||||
#: gtk/gtkconstraint.c:263
|
||||
@@ -2083,7 +2083,7 @@ msgstr "Egoeraren banderak"
|
||||
|
||||
#
|
||||
#: gtk/gtkcssnode.c:649 gtk/gtknativedialog.c:236 gtk/gtkstack.c:415
|
||||
#: gtk/gtktreeviewcolumn.c:272 gtk/gtkwidget.c:989
|
||||
#: gtk/gtktreeviewcolumn.c:272 gtk/gtkwidget.c:991
|
||||
msgid "Visible"
|
||||
msgstr "Ikusgai"
|
||||
|
||||
@@ -4562,7 +4562,7 @@ msgstr "Burbuila-leihoa kokatzeko posizioa"
|
||||
|
||||
#: gtk/gtkpopover.c:1359
|
||||
msgid "Whether to dismiss the popver on outside clicks"
|
||||
msgstr ""
|
||||
msgstr "Bunbuiloa baztertuko den ala ez kanpoko kliketan"
|
||||
|
||||
#: gtk/gtkpopover.c:1365 gtk/gtkwindow.c:1069
|
||||
msgid "Default widget"
|
||||
@@ -4583,7 +4583,7 @@ msgstr "Gezia marraztuko den ala ez"
|
||||
|
||||
#: gtk/gtkpopovermenubar.c:509
|
||||
msgid "The model from which the bar is made."
|
||||
msgstr ""
|
||||
msgstr "Barra egiteko erabili den eredua."
|
||||
|
||||
#: gtk/gtkpopovermenu.c:391
|
||||
msgid "Visible submenu"
|
||||
@@ -4896,35 +4896,35 @@ msgid "Whether the application has a selection"
|
||||
msgstr "Aplikazioak hautapen bat duen edo ez"
|
||||
|
||||
#
|
||||
#: gtk/gtkprogressbar.c:211
|
||||
#: gtk/gtkprogressbar.c:197
|
||||
msgid "Fraction"
|
||||
msgstr "Frakzioa"
|
||||
|
||||
#: gtk/gtkprogressbar.c:212
|
||||
#: gtk/gtkprogressbar.c:198
|
||||
msgid "The fraction of total work that has been completed"
|
||||
msgstr "Amaitu den lan guztiaren frakzioa"
|
||||
|
||||
#: gtk/gtkprogressbar.c:219
|
||||
#: gtk/gtkprogressbar.c:205
|
||||
msgid "Pulse Step"
|
||||
msgstr "Pultsuaren urratsa"
|
||||
|
||||
#: gtk/gtkprogressbar.c:220
|
||||
#: gtk/gtkprogressbar.c:206
|
||||
msgid "The fraction of total progress to move the bouncing block when pulsed"
|
||||
msgstr "Sakatutakoan errebote-blokeak egin beharreko progresio osoaren frakzioa"
|
||||
|
||||
#: gtk/gtkprogressbar.c:228
|
||||
#: gtk/gtkprogressbar.c:214
|
||||
msgid "Text to be displayed in the progress bar"
|
||||
msgstr "Progresio-barran bistaratu beharreko testua"
|
||||
|
||||
#: gtk/gtkprogressbar.c:247
|
||||
#: gtk/gtkprogressbar.c:233
|
||||
msgid "Show text"
|
||||
msgstr "Erakutsi testua"
|
||||
|
||||
#: gtk/gtkprogressbar.c:248
|
||||
#: gtk/gtkprogressbar.c:234
|
||||
msgid "Whether the progress is shown as text."
|
||||
msgstr "Progresioa testu gisa erakutsiko den ala ez adierazten du"
|
||||
|
||||
#: gtk/gtkprogressbar.c:267
|
||||
#: gtk/gtkprogressbar.c:253
|
||||
msgid ""
|
||||
"The preferred place to ellipsize the string, if the progress bar does not "
|
||||
"have enough room to display the entire string, if at all."
|
||||
@@ -5132,7 +5132,7 @@ msgstr "Edukiaren tamaina nola zehaztu behar den"
|
||||
msgid "Vertical Scrollable Policy"
|
||||
msgstr "Korritze-barra bertikalaren politika"
|
||||
|
||||
#: gtk/gtkscrollbar.c:236
|
||||
#: gtk/gtkscrollbar.c:199
|
||||
msgid "The GtkAdjustment that contains the current value of this scrollbar"
|
||||
msgstr "Korritze-barra honen uneko balioa duen GtkAdjustment"
|
||||
|
||||
@@ -5804,7 +5804,7 @@ msgstr "Norabide hauetan, taldearen tamainak osagai-trepetentzat eskatutako tama
|
||||
|
||||
#: gtk/gtkslicelistmodel.c:288
|
||||
msgid "Child model to take slice from"
|
||||
msgstr ""
|
||||
msgstr "Zatia hartzeko erabili den eredu haurra"
|
||||
|
||||
#: gtk/gtkslicelistmodel.c:299
|
||||
msgid "Offset"
|
||||
@@ -5973,7 +5973,7 @@ msgstr "Tamaina leunki aldatuko den ala ez (tamaina desberdineko umeen artean al
|
||||
|
||||
#: gtk/gtkstack.c:795
|
||||
msgid "A selection model with the stacks pages"
|
||||
msgstr ""
|
||||
msgstr "Pilen orriak dituen hautapen-eredu bat"
|
||||
|
||||
#: gtk/gtkstacksidebar.c:408 gtk/gtkstackswitcher.c:573
|
||||
#: gtk/gtkstackswitcher.c:574
|
||||
@@ -6102,7 +6102,7 @@ msgid "Whether the entry should grow and shrink with the content"
|
||||
msgstr "Sarrera handituko eta txikituko den edukiarekin batera"
|
||||
|
||||
#
|
||||
#: gtk/gtktexthandle.c:634 gtk/gtktexthandle.c:635 gtk/gtkwidget.c:953
|
||||
#: gtk/gtktexthandle.c:634 gtk/gtktexthandle.c:635 gtk/gtkwidget.c:955
|
||||
msgid "Parent widget"
|
||||
msgstr "Trepeta gurasoa"
|
||||
|
||||
@@ -6637,11 +6637,11 @@ msgstr "Bistaratutako erro-eredua"
|
||||
|
||||
#: gtk/gtktreelistmodel.c:730
|
||||
msgid "passthrough"
|
||||
msgstr ""
|
||||
msgstr "pasabidea"
|
||||
|
||||
#: gtk/gtktreelistmodel.c:731
|
||||
msgid "If child model values are passed through"
|
||||
msgstr ""
|
||||
msgstr "Eredu-balio haurrak pasatuko diren ala ez"
|
||||
|
||||
#: gtk/gtktreelistmodel.c:1047
|
||||
msgid "Children"
|
||||
@@ -6985,261 +6985,261 @@ msgid "Whether to use symbolic icons"
|
||||
msgstr "Ikono sinbolikoak erabiliko diren edo ez adierazten du"
|
||||
|
||||
#
|
||||
#: gtk/gtkwidget.c:946
|
||||
#: gtk/gtkwidget.c:948
|
||||
msgid "Widget name"
|
||||
msgstr "Trepeta-izena"
|
||||
|
||||
#: gtk/gtkwidget.c:947
|
||||
#: gtk/gtkwidget.c:949
|
||||
msgid "The name of the widget"
|
||||
msgstr "Trepetaren izena"
|
||||
|
||||
#: gtk/gtkwidget.c:954
|
||||
#: gtk/gtkwidget.c:956
|
||||
msgid "The parent widget of this widget."
|
||||
msgstr "Trepeta honen trepeta gurasoa."
|
||||
|
||||
#
|
||||
#: gtk/gtkwidget.c:966
|
||||
#: gtk/gtkwidget.c:968
|
||||
msgid "Root widget"
|
||||
msgstr "Erro-trepeta"
|
||||
|
||||
#: gtk/gtkwidget.c:967
|
||||
#: gtk/gtkwidget.c:969
|
||||
msgid "The root widget in the widget tree."
|
||||
msgstr "Trepeta-zuhaitzeko erro-trepeta."
|
||||
|
||||
#: gtk/gtkwidget.c:973
|
||||
#: gtk/gtkwidget.c:975
|
||||
msgid "Width request"
|
||||
msgstr "Zabalera-eskaera"
|
||||
|
||||
#: gtk/gtkwidget.c:974
|
||||
#: gtk/gtkwidget.c:976
|
||||
msgid ""
|
||||
"Override for width request of the widget, or -1 if natural request should be "
|
||||
"used"
|
||||
msgstr "Gainidatzi trepetaren zabalera-eskaera, edo -1 eskaera naturala erabili behar bada"
|
||||
|
||||
#: gtk/gtkwidget.c:981
|
||||
#: gtk/gtkwidget.c:983
|
||||
msgid "Height request"
|
||||
msgstr "Altuera-eskaera"
|
||||
|
||||
#: gtk/gtkwidget.c:982
|
||||
#: gtk/gtkwidget.c:984
|
||||
msgid ""
|
||||
"Override for height request of the widget, or -1 if natural request should "
|
||||
"be used"
|
||||
msgstr "Gainidatzi trepetaren altuera-eskaera, edo -1 eskaera naturala erabili behar bada"
|
||||
|
||||
#: gtk/gtkwidget.c:990
|
||||
#: gtk/gtkwidget.c:992
|
||||
msgid "Whether the widget is visible"
|
||||
msgstr "Trepeta ikusgai dagoen ala ez adierazten du"
|
||||
|
||||
#: gtk/gtkwidget.c:997
|
||||
#: gtk/gtkwidget.c:999
|
||||
msgid "Whether the widget responds to input"
|
||||
msgstr "Trepetak sarrerari erantzuten dion ala ez adierazten du"
|
||||
|
||||
#: gtk/gtkwidget.c:1003
|
||||
#: gtk/gtkwidget.c:1005
|
||||
msgid "Can focus"
|
||||
msgstr "Enfoka dezake"
|
||||
|
||||
#: gtk/gtkwidget.c:1004
|
||||
#: gtk/gtkwidget.c:1006
|
||||
msgid "Whether the widget can accept the input focus"
|
||||
msgstr "Trepetak sarrera-fokua onar dezakeen ala ez adierazten du"
|
||||
|
||||
#: gtk/gtkwidget.c:1010
|
||||
#: gtk/gtkwidget.c:1012
|
||||
msgid "Has focus"
|
||||
msgstr "Fokua du"
|
||||
|
||||
#: gtk/gtkwidget.c:1011
|
||||
#: gtk/gtkwidget.c:1013
|
||||
msgid "Whether the widget has the input focus"
|
||||
msgstr "Trepetak sarrera-fokua duen ala ez adierazten du"
|
||||
|
||||
#: gtk/gtkwidget.c:1017
|
||||
#: gtk/gtkwidget.c:1019
|
||||
msgid "Is focus"
|
||||
msgstr "Fokua da"
|
||||
|
||||
#: gtk/gtkwidget.c:1018
|
||||
#: gtk/gtkwidget.c:1020
|
||||
msgid "Whether the widget is the focus widget within the toplevel"
|
||||
msgstr "Trepeta goi-mailakoaren barruan foku-trepeta den ala ez adierazten du"
|
||||
|
||||
#: gtk/gtkwidget.c:1024
|
||||
#: gtk/gtkwidget.c:1026
|
||||
msgid "Can target"
|
||||
msgstr ""
|
||||
msgstr "Helburua izan daiteke"
|
||||
|
||||
#: gtk/gtkwidget.c:1025
|
||||
#: gtk/gtkwidget.c:1027
|
||||
msgid "Whether the widget can receive pointer events"
|
||||
msgstr ""
|
||||
msgstr "Trepetak erakuslearen gertaerak jaso ditzakeen ala ez"
|
||||
|
||||
#: gtk/gtkwidget.c:1041
|
||||
#: gtk/gtkwidget.c:1043
|
||||
msgid "Focus on click"
|
||||
msgstr "Fokua klik egindakoan"
|
||||
|
||||
#: gtk/gtkwidget.c:1042
|
||||
#: gtk/gtkwidget.c:1044
|
||||
msgid "Whether the widget should grab focus when it is clicked with the mouse"
|
||||
msgstr "Trepetak saguaren klik jasotakoan fokua hartzen duen ala ez adierazten du"
|
||||
|
||||
#
|
||||
#: gtk/gtkwidget.c:1048
|
||||
#: gtk/gtkwidget.c:1050
|
||||
msgid "Has default"
|
||||
msgstr "Lehenetsia dauka"
|
||||
|
||||
#: gtk/gtkwidget.c:1049
|
||||
#: gtk/gtkwidget.c:1051
|
||||
msgid "Whether the widget is the default widget"
|
||||
msgstr "Trepeta trepeta lehenetsia den ala ez adierazten du"
|
||||
|
||||
#: gtk/gtkwidget.c:1055
|
||||
#: gtk/gtkwidget.c:1057
|
||||
msgid "Receives default"
|
||||
msgstr "Lehenetsia jasotzen du"
|
||||
|
||||
#: gtk/gtkwidget.c:1056
|
||||
#: gtk/gtkwidget.c:1058
|
||||
msgid "If TRUE, the widget will receive the default action when it is focused"
|
||||
msgstr "TRUE (egia) bada, trepetak ekintza lehenetsia jasoko du enfokatutakoan"
|
||||
|
||||
#: gtk/gtkwidget.c:1068
|
||||
#: gtk/gtkwidget.c:1070
|
||||
msgid "The cursor to show when hoving above widget"
|
||||
msgstr ""
|
||||
msgstr "Trepetaren gainetik igarotzean erakutsiko den kurtsorea"
|
||||
|
||||
#: gtk/gtkwidget.c:1082
|
||||
#: gtk/gtkwidget.c:1084
|
||||
msgid "Has tooltip"
|
||||
msgstr "Argibidea du"
|
||||
|
||||
#: gtk/gtkwidget.c:1083
|
||||
#: gtk/gtkwidget.c:1085
|
||||
msgid "Whether this widget has a tooltip"
|
||||
msgstr "Trepetak argibidea duen edo ez"
|
||||
|
||||
#: gtk/gtkwidget.c:1104
|
||||
#: gtk/gtkwidget.c:1106
|
||||
msgid "Tooltip Text"
|
||||
msgstr "Argibidearen testua"
|
||||
|
||||
#: gtk/gtkwidget.c:1105 gtk/gtkwidget.c:1127
|
||||
#: gtk/gtkwidget.c:1107 gtk/gtkwidget.c:1129
|
||||
msgid "The contents of the tooltip for this widget"
|
||||
msgstr "Trepetaren argibidearen edukia"
|
||||
|
||||
#: gtk/gtkwidget.c:1126
|
||||
#: gtk/gtkwidget.c:1128
|
||||
msgid "Tooltip markup"
|
||||
msgstr "Markaren argibidea"
|
||||
|
||||
#: gtk/gtkwidget.c:1139
|
||||
#: gtk/gtkwidget.c:1141
|
||||
msgid "How to position in extra horizontal space"
|
||||
msgstr "Nola kokatu leku horizontal gehigarrian"
|
||||
|
||||
#: gtk/gtkwidget.c:1152
|
||||
#: gtk/gtkwidget.c:1154
|
||||
msgid "How to position in extra vertical space"
|
||||
msgstr "Nola kokatu leku bertikal gehigarrian"
|
||||
|
||||
#: gtk/gtkwidget.c:1169
|
||||
#: gtk/gtkwidget.c:1171
|
||||
msgid "Margin on Start"
|
||||
msgstr "Hasierako marjina"
|
||||
|
||||
#: gtk/gtkwidget.c:1170
|
||||
#: gtk/gtkwidget.c:1172
|
||||
msgid "Pixels of extra space on the start"
|
||||
msgstr "Hasierako tarte gehigarriaren pixelak"
|
||||
|
||||
#: gtk/gtkwidget.c:1187
|
||||
#: gtk/gtkwidget.c:1189
|
||||
msgid "Margin on End"
|
||||
msgstr "Amaierako marjina"
|
||||
|
||||
#: gtk/gtkwidget.c:1188
|
||||
#: gtk/gtkwidget.c:1190
|
||||
msgid "Pixels of extra space on the end"
|
||||
msgstr "Amaierako tarte gehigarriaren pixelak"
|
||||
|
||||
#: gtk/gtkwidget.c:1204
|
||||
#: gtk/gtkwidget.c:1206
|
||||
msgid "Margin on Top"
|
||||
msgstr "Marjina goian"
|
||||
|
||||
#: gtk/gtkwidget.c:1205
|
||||
#: gtk/gtkwidget.c:1207
|
||||
msgid "Pixels of extra space on the top side"
|
||||
msgstr "Goi aldeko tarte gehigarriaren pixelak"
|
||||
|
||||
#: gtk/gtkwidget.c:1221
|
||||
#: gtk/gtkwidget.c:1223
|
||||
msgid "Margin on Bottom"
|
||||
msgstr "Marjina behean"
|
||||
|
||||
#: gtk/gtkwidget.c:1222
|
||||
#: gtk/gtkwidget.c:1224
|
||||
msgid "Pixels of extra space on the bottom side"
|
||||
msgstr "Leku gehigarriaren pixelak beheko alboan"
|
||||
|
||||
#: gtk/gtkwidget.c:1235
|
||||
#: gtk/gtkwidget.c:1237
|
||||
msgid "All Margins"
|
||||
msgstr "Marjina guztiak"
|
||||
|
||||
#: gtk/gtkwidget.c:1236
|
||||
#: gtk/gtkwidget.c:1238
|
||||
msgid "Pixels of extra space on all four sides"
|
||||
msgstr "Leku gehigarriaren pixelak lau alboetan"
|
||||
|
||||
#: gtk/gtkwidget.c:1248
|
||||
#: gtk/gtkwidget.c:1250
|
||||
msgid "Horizontal Expand"
|
||||
msgstr "Betegarri horizontala"
|
||||
|
||||
#: gtk/gtkwidget.c:1249
|
||||
#: gtk/gtkwidget.c:1251
|
||||
msgid "Whether widget wants more horizontal space"
|
||||
msgstr "Trepetak tarte horizontal gehiago nahi duen edo ez"
|
||||
|
||||
#: gtk/gtkwidget.c:1260
|
||||
#: gtk/gtkwidget.c:1262
|
||||
msgid "Horizontal Expand Set"
|
||||
msgstr "Betegarri horizontala ezarrita"
|
||||
|
||||
#: gtk/gtkwidget.c:1261
|
||||
#: gtk/gtkwidget.c:1263
|
||||
msgid "Whether to use the hexpand property"
|
||||
msgstr "'hexpand' (betegarri horizontala) propietatea erabiliko den edo ez"
|
||||
|
||||
#: gtk/gtkwidget.c:1272
|
||||
#: gtk/gtkwidget.c:1274
|
||||
msgid "Vertical Expand"
|
||||
msgstr "Betegarri bertikala"
|
||||
|
||||
#: gtk/gtkwidget.c:1273
|
||||
#: gtk/gtkwidget.c:1275
|
||||
msgid "Whether widget wants more vertical space"
|
||||
msgstr "Trepetak tarte bertikal gehiago nahi duen edo ez"
|
||||
|
||||
#: gtk/gtkwidget.c:1284
|
||||
#: gtk/gtkwidget.c:1286
|
||||
msgid "Vertical Expand Set"
|
||||
msgstr "Betegarri bertikala ezarrita"
|
||||
|
||||
#: gtk/gtkwidget.c:1285
|
||||
#: gtk/gtkwidget.c:1287
|
||||
msgid "Whether to use the vexpand property"
|
||||
msgstr "'vexpand' (betegarri bertikala) propietatea erabiliko den edo ez"
|
||||
|
||||
#: gtk/gtkwidget.c:1296
|
||||
#: gtk/gtkwidget.c:1298
|
||||
msgid "Expand Both"
|
||||
msgstr "Zabaldu biak"
|
||||
|
||||
#: gtk/gtkwidget.c:1297
|
||||
#: gtk/gtkwidget.c:1299
|
||||
msgid "Whether widget wants to expand in both directions"
|
||||
msgstr "Trepetak bi norabideetan zabaltzea nahi duen edo ez"
|
||||
|
||||
#: gtk/gtkwidget.c:1311
|
||||
#: gtk/gtkwidget.c:1313
|
||||
msgid "Opacity for Widget"
|
||||
msgstr "Trepetaren opakutasuna"
|
||||
|
||||
#: gtk/gtkwidget.c:1312
|
||||
#: gtk/gtkwidget.c:1314
|
||||
msgid "The opacity of the widget, from 0 to 1"
|
||||
msgstr "Trepetaren opakutasuna, 0 eta 1 artekoa"
|
||||
|
||||
#: gtk/gtkwidget.c:1324
|
||||
#: gtk/gtkwidget.c:1326
|
||||
msgid "Overflow"
|
||||
msgstr "Gainezkatzea"
|
||||
|
||||
#: gtk/gtkwidget.c:1325
|
||||
#: gtk/gtkwidget.c:1327
|
||||
msgid "How content outside the widget’s content area is treated"
|
||||
msgstr "Trepetaren eduki-areatik kanpoko edukia nola tratatuko den"
|
||||
|
||||
#: gtk/gtkwidget.c:1338
|
||||
#: gtk/gtkwidget.c:1340
|
||||
msgid "Scale factor"
|
||||
msgstr "Eskalatzeko faktorea"
|
||||
|
||||
#: gtk/gtkwidget.c:1339
|
||||
#: gtk/gtkwidget.c:1341
|
||||
msgid "The scaling factor of the window"
|
||||
msgstr "Leihoaren eskalatzeko faktorea"
|
||||
|
||||
#: gtk/gtkwidget.c:1351
|
||||
#: gtk/gtkwidget.c:1353
|
||||
msgid "CSS Name"
|
||||
msgstr "CSS izena"
|
||||
|
||||
#: gtk/gtkwidget.c:1352
|
||||
#: gtk/gtkwidget.c:1354
|
||||
msgid "The name of this widget in the CSS tree"
|
||||
msgstr "Trepetaren honen izena CSS zuhaitzean"
|
||||
|
||||
#: gtk/gtkwidget.c:1364
|
||||
#: gtk/gtkwidget.c:1366
|
||||
msgid "Layout Manager"
|
||||
msgstr "Diseinu-kudeatzailea"
|
||||
|
||||
#: gtk/gtkwidget.c:1365
|
||||
#: gtk/gtkwidget.c:1367
|
||||
msgid "The layout manager used to layout children of the widget"
|
||||
msgstr "Trepetaren haurrak diseinatzeko erabilitako diseinu-kudeatzailea"
|
||||
|
||||
|
||||
+322
-267
File diff suppressed because it is too large
Load Diff
@@ -287,7 +287,6 @@ gtk/gtkswitch.c
|
||||
gtk/gtktextbuffer.c
|
||||
gtk/gtktext.c
|
||||
gtk/gtktextchild.c
|
||||
gtk/gtktextdisplay.c
|
||||
gtk/gtktexthandle.c
|
||||
gtk/gtktextiter.c
|
||||
gtk/gtktextlayout.c
|
||||
|
||||
@@ -19,6 +19,7 @@ demos/gtk-demo/filtermodel.ui
|
||||
demos/gtk-demo/fishbowl.ui
|
||||
demos/gtk-demo/font_features.c
|
||||
demos/gtk-demo/font-features.ui
|
||||
demos/gtk-demo/fontrendering.ui
|
||||
demos/gtk-demo/iconview.c
|
||||
demos/gtk-demo/infobar.c
|
||||
demos/gtk-demo/listbox.ui
|
||||
|
||||
@@ -3380,7 +3380,7 @@ msgstr "Dreceres de cerca"
|
||||
#: gtk/gtkshortcutswindow.c:1039 gtk/ui/gtkemojichooser.ui:320
|
||||
#: gtk/ui/gtkfilechooserwidget.ui:293
|
||||
msgid "No Results Found"
|
||||
msgstr "No s'ha trobat cap tipus de lletra"
|
||||
msgstr "No s'ha trobat cap resultat"
|
||||
|
||||
#: gtk/gtkshortcutswindow.c:1045 gtk/ui/gtkemojichooser.ui:333
|
||||
#: gtk/ui/gtkfilechooserwidget.ui:306 gtk/ui/gtkplacesview.ui:247
|
||||
|
||||
@@ -16,15 +16,15 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gtk+.master\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2019-06-23 07:58+0000\n"
|
||||
"PO-Revision-Date: 2019-06-24 09:57+0200\n"
|
||||
"POT-Creation-Date: 2019-07-30 05:07+0000\n"
|
||||
"PO-Revision-Date: 2019-07-30 09:27+0200\n"
|
||||
"Last-Translator: Daniel Mustieles <daniel.mustieles@gmail.com>\n"
|
||||
"Language-Team: es <gnome-es-list@gnome.org>\n"
|
||||
"Language: es\n"
|
||||
"Language-Team: Spanish - Spain <gnome-es-list@gnome.org>\n"
|
||||
"Language: es_ES\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Gtranslator 3.32.0\n"
|
||||
"X-Generator: Gtranslator 3.32.1\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: gdk/broadway/gdkbroadway-server.c:133
|
||||
@@ -64,15 +64,15 @@ msgstr "No se soporta arrastrar y soltar desde otras aplicaciones."
|
||||
msgid "No compatible formats to transfer contents."
|
||||
msgstr "No hay formatos compatibles para transferir el contenido."
|
||||
|
||||
#: gdk/gdksurface.c:1160
|
||||
#: gdk/gdksurface.c:1157
|
||||
msgid "GL support disabled via GDK_DEBUG"
|
||||
msgstr "Soporte de GL desactivado mediante GDK_DEBUG"
|
||||
|
||||
#: gdk/gdksurface.c:1171
|
||||
#: gdk/gdksurface.c:1168
|
||||
msgid "The current backend does not support OpenGL"
|
||||
msgstr "El «backend» actual no soporta OpenGL"
|
||||
|
||||
#: gdk/gdksurface.c:1279
|
||||
#: gdk/gdksurface.c:1276
|
||||
msgid "Vulkan support disabled via GDK_DEBUG"
|
||||
msgstr "Soporte de Vulkan desactivado mediante GDK_DEBUG"
|
||||
|
||||
@@ -701,13 +701,13 @@ msgstr "COLORES"
|
||||
|
||||
#: gdk/x11/gdkapplaunchcontext-x11.c:292
|
||||
#, c-format
|
||||
msgid "Starting %s"
|
||||
msgstr "Iniciando %s"
|
||||
msgid "Starting “%s”"
|
||||
msgstr "Iniciando «%s»"
|
||||
|
||||
#: gdk/x11/gdkapplaunchcontext-x11.c:305
|
||||
#, c-format
|
||||
msgid "Opening %s"
|
||||
msgstr "Abriendo %s"
|
||||
msgid "Opening “%s”"
|
||||
msgstr "Abriendo «%s»"
|
||||
|
||||
#: gdk/x11/gdkapplaunchcontext-x11.c:310
|
||||
#, c-format
|
||||
@@ -887,15 +887,15 @@ msgctxt "Stock label"
|
||||
msgid "_Close"
|
||||
msgstr "_Cerrar"
|
||||
|
||||
#: gtk/a11y/gtkimageaccessible.c:60 gtk/gtkheaderbar.c:421 gtk/gtkwindow.c:6721
|
||||
#: gtk/a11y/gtkimageaccessible.c:60 gtk/gtkheaderbar.c:421 gtk/gtkwindow.c:6737
|
||||
msgid "Minimize"
|
||||
msgstr "Minimizar"
|
||||
|
||||
#: gtk/a11y/gtkimageaccessible.c:61 gtk/gtkheaderbar.c:444 gtk/gtkwindow.c:6730
|
||||
#: gtk/a11y/gtkimageaccessible.c:61 gtk/gtkheaderbar.c:444 gtk/gtkwindow.c:6746
|
||||
msgid "Maximize"
|
||||
msgstr "Maximizar"
|
||||
|
||||
#: gtk/a11y/gtkimageaccessible.c:62 gtk/gtkheaderbar.c:444 gtk/gtkwindow.c:6687
|
||||
#: gtk/a11y/gtkimageaccessible.c:62 gtk/gtkheaderbar.c:444 gtk/gtkwindow.c:6703
|
||||
msgid "Restore"
|
||||
msgstr "Restaurar"
|
||||
|
||||
@@ -1883,20 +1883,20 @@ msgid "White"
|
||||
msgstr "Blanco"
|
||||
|
||||
#. translators: label for the custom section in the color chooser
|
||||
#: gtk/gtkcolorchooserwidget.c:551
|
||||
#: gtk/gtkcolorchooserwidget.c:549
|
||||
msgid "Custom"
|
||||
msgstr "Personalizada"
|
||||
|
||||
#: gtk/gtkcolorchooserwidget.c:562
|
||||
#: gtk/gtkcolorchooserwidget.c:560
|
||||
msgid "Custom color"
|
||||
msgstr "Color personalizado"
|
||||
|
||||
# C en conflicto con Cancelar
|
||||
#: gtk/gtkcolorchooserwidget.c:563
|
||||
#: gtk/gtkcolorchooserwidget.c:561
|
||||
msgid "Create a custom color"
|
||||
msgstr "Crear un color personalizado"
|
||||
|
||||
#: gtk/gtkcolorchooserwidget.c:582
|
||||
#: gtk/gtkcolorchooserwidget.c:580
|
||||
#, c-format
|
||||
msgid "Custom color %d: %s"
|
||||
msgstr "Color personalizado %d: %s"
|
||||
@@ -1915,7 +1915,7 @@ msgctxt "Color channel"
|
||||
msgid "Alpha"
|
||||
msgstr "Alfa"
|
||||
|
||||
#: gtk/gtkcolorswatch.c:289
|
||||
#: gtk/gtkcolorswatch.c:287
|
||||
msgid "Customize"
|
||||
msgstr "Personalizar"
|
||||
|
||||
@@ -1983,7 +1983,7 @@ msgstr "_Derecho:"
|
||||
msgid "Paper Margins"
|
||||
msgstr "Márgenes del papel"
|
||||
|
||||
#: gtk/gtkentry.c:3502
|
||||
#: gtk/gtkentry.c:3527
|
||||
msgid "Insert Emoji"
|
||||
msgstr "Insertar emoticono"
|
||||
|
||||
@@ -2065,12 +2065,12 @@ msgid "A file with that name already exists"
|
||||
msgstr "Ya existe un archivo con ese nombre"
|
||||
|
||||
#: gtk/gtkfilechoosernative.c:525 gtk/gtkfilechoosernative.c:603
|
||||
#: gtk/gtkfilechooserwidget.c:1464 gtk/gtkfilechooserwidget.c:6322
|
||||
#: gtk/gtkfilechooserwidget.c:1464 gtk/gtkfilechooserwidget.c:6334
|
||||
#: gtk/gtkmessagedialog.c:791 gtk/gtkmessagedialog.c:800
|
||||
#: gtk/gtkmountoperation.c:543 gtk/gtkpagesetupunixdialog.c:210
|
||||
#: gtk/gtkmountoperation.c:592 gtk/gtkpagesetupunixdialog.c:210
|
||||
#: gtk/gtkprintbackend.c:657 gtk/gtkprinteroptionwidget.c:545
|
||||
#: gtk/gtkprintunixdialog.c:680 gtk/gtkprintunixdialog.c:746
|
||||
#: gtk/gtkwindow.c:9009 gtk/inspector/css-editor.c:237
|
||||
#: gtk/gtkwindow.c:9026 gtk/inspector/css-editor.c:237
|
||||
#: gtk/inspector/recorder.c:1026 gtk/ui/gtkappchooserdialog.ui:46
|
||||
#: gtk/ui/gtkassistant.ui:50 gtk/ui/gtkcolorchooserdialog.ui:28
|
||||
#: gtk/ui/gtkfontchooserdialog.ui:22
|
||||
@@ -2172,7 +2172,7 @@ msgid "If you delete an item, it will be permanently lost."
|
||||
msgstr "Si elimina un elemento, se perderña definitivamente."
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:1465 gtk/gtkfilechooserwidget.c:2199
|
||||
#: gtk/gtklabel.c:6096 gtk/gtktext.c:5768 gtk/gtktextview.c:8628
|
||||
#: gtk/gtklabel.c:6106 gtk/gtktext.c:5781 gtk/gtktextview.c:8667
|
||||
msgid "_Delete"
|
||||
msgstr "_Eliminar"
|
||||
|
||||
@@ -2218,7 +2218,6 @@ msgid "Show _Size Column"
|
||||
msgstr "Mostrar columna de _tamaño"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:2206
|
||||
#| msgid "Show _Size Column"
|
||||
msgid "Show T_ype Column"
|
||||
msgstr "Mostrar columna de t_ipo"
|
||||
|
||||
@@ -2231,169 +2230,162 @@ msgid "Sort _Folders before Files"
|
||||
msgstr "Ordenar _carpetas antes que archivos"
|
||||
|
||||
#. this is the header for the location column in the print dialog
|
||||
#: gtk/gtkfilechooserwidget.c:2509 gtk/inspector/css-node-tree.ui:133
|
||||
#: gtk/gtkfilechooserwidget.c:2505 gtk/inspector/css-node-tree.ui:133
|
||||
#: gtk/ui/gtkfilechooserwidget.ui:194 gtk/ui/gtkprintunixdialog.ui:108
|
||||
msgid "Location"
|
||||
msgstr "Lugar"
|
||||
|
||||
#. Label
|
||||
#: gtk/gtkfilechooserwidget.c:2602
|
||||
#: gtk/gtkfilechooserwidget.c:2598
|
||||
msgid "_Name:"
|
||||
msgstr "_Nombre:"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:3226 gtk/gtkfilechooserwidget.c:3240
|
||||
#: gtk/gtkfilechooserwidget.c:3239 gtk/gtkfilechooserwidget.c:3253
|
||||
#, c-format
|
||||
msgid "Searching in %s"
|
||||
msgstr "Buscando en %s"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:3246
|
||||
#: gtk/gtkfilechooserwidget.c:3259
|
||||
msgid "Searching"
|
||||
msgstr "Buscando"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:3253
|
||||
#: gtk/gtkfilechooserwidget.c:3266
|
||||
msgid "Enter location"
|
||||
msgstr "Introducir ubicación"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:3255
|
||||
#: gtk/gtkfilechooserwidget.c:3268
|
||||
msgid "Enter location or URL"
|
||||
msgstr "Introducir ubicación o URL"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4263 gtk/gtkfilechooserwidget.c:7232
|
||||
#: gtk/gtkfilechooserwidget.c:4275 gtk/gtkfilechooserwidget.c:7244
|
||||
#: gtk/ui/gtkfilechooserwidget.ui:234
|
||||
msgid "Modified"
|
||||
msgstr "Modificado"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4541
|
||||
#: gtk/gtkfilechooserwidget.c:4553
|
||||
#, c-format
|
||||
msgid "Could not read the contents of %s"
|
||||
msgstr "No se pudo leer el contenido de %s"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4545
|
||||
#: gtk/gtkfilechooserwidget.c:4557
|
||||
msgid "Could not read the contents of the folder"
|
||||
msgstr "No se pudo leer el contenido del la carpeta"
|
||||
|
||||
#. Translators: see g_date_time_format() for details on the format
|
||||
#: gtk/gtkfilechooserwidget.c:4670 gtk/gtkfilechooserwidget.c:4714
|
||||
#: gtk/gtkfilechooserwidget.c:4682 gtk/gtkfilechooserwidget.c:4726
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4672 gtk/gtkfilechooserwidget.c:4716
|
||||
#: gtk/gtkfilechooserwidget.c:4684 gtk/gtkfilechooserwidget.c:4728
|
||||
msgid "%l:%M %p"
|
||||
msgstr "%l:%M %p"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4676
|
||||
#: gtk/gtkfilechooserwidget.c:4688
|
||||
msgid "Yesterday"
|
||||
msgstr "Ayer"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4684
|
||||
#: gtk/gtkfilechooserwidget.c:4696
|
||||
msgid "%-e %b"
|
||||
msgstr "%-e %b"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4688
|
||||
#: gtk/gtkfilechooserwidget.c:4700
|
||||
msgid "%-e %b %Y"
|
||||
msgstr "%-e %b %Y"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4778 gtk/gtkfilechooserwidget.c:4786
|
||||
#: gtk/gtkfilechooserwidget.c:4790 gtk/gtkfilechooserwidget.c:4798
|
||||
msgid "Program"
|
||||
msgstr "Programa"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4779
|
||||
#| msgctxt "keyboard label"
|
||||
#| msgid "AudioMute"
|
||||
#: gtk/gtkfilechooserwidget.c:4791
|
||||
msgid "Audio"
|
||||
msgstr "Sonido"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4780 gtk/gtkfontbutton.c:611
|
||||
#: gtk/gtkfilechooserwidget.c:4792 gtk/gtkfontbutton.c:611
|
||||
#: gtk/inspector/visual.ui:187
|
||||
msgid "Font"
|
||||
msgstr "Tipografía"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4781
|
||||
#: gtk/gtkfilechooserwidget.c:4793
|
||||
msgid "Image"
|
||||
msgstr "Imagen"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4782
|
||||
#| msgctxt "paper size"
|
||||
#| msgid "Arch A"
|
||||
#: gtk/gtkfilechooserwidget.c:4794
|
||||
msgid "Archive"
|
||||
msgstr "Archivador"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4783
|
||||
#: gtk/gtkfilechooserwidget.c:4795
|
||||
msgid "Markup"
|
||||
msgstr "Marcado"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4784 gtk/gtkfilechooserwidget.c:4785
|
||||
#: gtk/gtkfilechooserwidget.c:4796 gtk/gtkfilechooserwidget.c:4797
|
||||
msgid "Text"
|
||||
msgstr "Texto"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4787
|
||||
#: gtk/gtkfilechooserwidget.c:4799
|
||||
msgid "Video"
|
||||
msgstr "Vídeo"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4788
|
||||
#: gtk/gtkfilechooserwidget.c:4800
|
||||
msgid "Contacts"
|
||||
msgstr "Contactos"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4789
|
||||
#| msgid "calendar:MY"
|
||||
#: gtk/gtkfilechooserwidget.c:4801
|
||||
msgid "Calendar"
|
||||
msgstr "Calendario"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4790
|
||||
#| msgid "Documented by"
|
||||
#: gtk/gtkfilechooserwidget.c:4802
|
||||
msgid "Document"
|
||||
msgstr "Documento"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4791
|
||||
#| msgid "_Orientation:"
|
||||
#: gtk/gtkfilechooserwidget.c:4803
|
||||
msgid "Presentation"
|
||||
msgstr "Presentación"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4792
|
||||
#: gtk/gtkfilechooserwidget.c:4804
|
||||
msgid "Spreadsheet"
|
||||
msgstr "Hoja de cálculo"
|
||||
|
||||
#. Translators: We don't know whether this printer is
|
||||
#. * available to print to.
|
||||
#: gtk/gtkfilechooserwidget.c:4823 gtk/gtkfilechooserwidget.c:5007
|
||||
#: gtk/gtkfilechooserwidget.c:4835 gtk/gtkfilechooserwidget.c:5019
|
||||
#: gtk/inspector/prop-editor.c:1506
|
||||
#: modules/printbackends/gtkprintbackendcloudprint.c:731
|
||||
msgid "Unknown"
|
||||
msgstr "Desconocido"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:5046 gtk/gtkplacessidebar.c:1087
|
||||
#: gtk/gtkfilechooserwidget.c:5058 gtk/gtkplacessidebar.c:1087
|
||||
msgid "Home"
|
||||
msgstr "Carpeta personal"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:5540
|
||||
#: gtk/gtkfilechooserwidget.c:5552
|
||||
msgid "Cannot change to folder because it is not local"
|
||||
msgstr "No se pudo cambiar a la carpeta porque no es local"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:6315 gtk/gtkprintunixdialog.c:671
|
||||
#: gtk/gtkfilechooserwidget.c:6327 gtk/gtkprintunixdialog.c:671
|
||||
#, c-format
|
||||
msgid "A file named “%s” already exists. Do you want to replace it?"
|
||||
msgstr "Ya existe un archivo llamado «%s». ¿Quiere reemplazarlo?"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:6318 gtk/gtkprintunixdialog.c:675
|
||||
#: gtk/gtkfilechooserwidget.c:6330 gtk/gtkprintunixdialog.c:675
|
||||
#, c-format
|
||||
msgid ""
|
||||
"The file already exists in “%s”. Replacing it will overwrite its contents."
|
||||
msgstr ""
|
||||
"El archivo ya existe en «%s». Si lo reemplaza sobrescribirá su contenido."
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:6323 gtk/gtkprintunixdialog.c:683
|
||||
#: gtk/gtkfilechooserwidget.c:6335 gtk/gtkprintunixdialog.c:683
|
||||
msgid "_Replace"
|
||||
msgstr "_Reemplazar"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:6531
|
||||
#: gtk/gtkfilechooserwidget.c:6543
|
||||
msgid "You do not have access to the specified folder."
|
||||
msgstr "No tiene acceso a la carpeta especificada."
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:7155
|
||||
#: gtk/gtkfilechooserwidget.c:7167
|
||||
msgid "Could not send the search request"
|
||||
msgstr "No se ha podido enviar la petición de búsqueda"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:7450
|
||||
#: gtk/gtkfilechooserwidget.c:7462
|
||||
msgid "Accessed"
|
||||
msgstr "Accedido"
|
||||
|
||||
@@ -2476,7 +2468,7 @@ msgstr "Falló al crear el contexto de OpenGL"
|
||||
msgid "Application menu"
|
||||
msgstr "Menú de la aplicación"
|
||||
|
||||
#: gtk/gtkheaderbar.c:462 gtk/gtkwindow.c:6757
|
||||
#: gtk/gtkheaderbar.c:462 gtk/gtkwindow.c:6773
|
||||
msgid "Close"
|
||||
msgstr "Cerrar"
|
||||
|
||||
@@ -2505,27 +2497,27 @@ msgstr "Advertencia"
|
||||
msgid "Error"
|
||||
msgstr "Error"
|
||||
|
||||
#: gtk/gtklabel.c:6093 gtk/gtktext.c:5756 gtk/gtktextview.c:8616
|
||||
#: gtk/gtklabel.c:6103 gtk/gtktext.c:5769 gtk/gtktextview.c:8655
|
||||
msgid "Cu_t"
|
||||
msgstr "Cor_tar"
|
||||
|
||||
#: gtk/gtklabel.c:6094 gtk/gtktext.c:5760 gtk/gtktextview.c:8620
|
||||
#: gtk/gtklabel.c:6104 gtk/gtktext.c:5773 gtk/gtktextview.c:8659
|
||||
msgid "_Copy"
|
||||
msgstr "_Copiar"
|
||||
|
||||
#: gtk/gtklabel.c:6095 gtk/gtktext.c:5764 gtk/gtktextview.c:8624
|
||||
#: gtk/gtklabel.c:6105 gtk/gtktext.c:5777 gtk/gtktextview.c:8663
|
||||
msgid "_Paste"
|
||||
msgstr "_Pegar"
|
||||
|
||||
#: gtk/gtklabel.c:6101 gtk/gtktext.c:5777 gtk/gtktextview.c:8637
|
||||
#: gtk/gtklabel.c:6111 gtk/gtktext.c:5790 gtk/gtktextview.c:8676
|
||||
msgid "Select _All"
|
||||
msgstr "Seleccionar _todo"
|
||||
|
||||
#: gtk/gtklabel.c:6106
|
||||
#: gtk/gtklabel.c:6116
|
||||
msgid "_Open Link"
|
||||
msgstr "_Abrir enlace"
|
||||
|
||||
#: gtk/gtklabel.c:6110
|
||||
#: gtk/gtklabel.c:6120
|
||||
msgid "Copy _Link Address"
|
||||
msgstr "Copiar la dirección del _enlace"
|
||||
|
||||
@@ -2574,7 +2566,7 @@ msgstr ""
|
||||
#. * Do *not* translate it to "predefinito:LTR", if it
|
||||
#. * it isn't default:LTR or default:RTL it will not work
|
||||
#.
|
||||
#: gtk/gtkmain.c:976
|
||||
#: gtk/gtkmain.c:977
|
||||
msgid "default:LTR"
|
||||
msgstr "default:LTR"
|
||||
|
||||
@@ -2627,7 +2619,7 @@ msgid "%d:%02d"
|
||||
msgstr "%d:%02d"
|
||||
|
||||
#: gtk/gtkmessagedialog.c:783 gtk/gtkmessagedialog.c:801
|
||||
#: gtk/gtkprintbackend.c:658 gtk/gtkwindow.c:9010
|
||||
#: gtk/gtkprintbackend.c:658 gtk/gtkwindow.c:9027
|
||||
msgid "_OK"
|
||||
msgstr "_Aceptar"
|
||||
|
||||
@@ -2639,57 +2631,73 @@ msgstr "_No"
|
||||
msgid "_Yes"
|
||||
msgstr "_Sí"
|
||||
|
||||
#: gtk/gtkmountoperation.c:544
|
||||
#: gtk/gtkmountoperation.c:593
|
||||
msgid "Co_nnect"
|
||||
msgstr "Co_nectar"
|
||||
|
||||
#: gtk/gtkmountoperation.c:611
|
||||
#: gtk/gtkmountoperation.c:660
|
||||
msgid "Connect As"
|
||||
msgstr "Conectar como"
|
||||
|
||||
#: gtk/gtkmountoperation.c:620
|
||||
#: gtk/gtkmountoperation.c:669
|
||||
msgid "_Anonymous"
|
||||
msgstr "_Anónimo"
|
||||
|
||||
#: gtk/gtkmountoperation.c:628
|
||||
#: gtk/gtkmountoperation.c:677
|
||||
msgid "Registered U_ser"
|
||||
msgstr "U_suario registrado"
|
||||
|
||||
#: gtk/gtkmountoperation.c:638
|
||||
#: gtk/gtkmountoperation.c:687
|
||||
msgid "_Username"
|
||||
msgstr "Nombre de _usuario"
|
||||
|
||||
#: gtk/gtkmountoperation.c:643
|
||||
#: gtk/gtkmountoperation.c:692
|
||||
msgid "_Domain"
|
||||
msgstr "_Dominio"
|
||||
|
||||
#: gtk/gtkmountoperation.c:649
|
||||
#: gtk/gtkmountoperation.c:701
|
||||
msgid "Volume type"
|
||||
msgstr "Tipo de volumen"
|
||||
|
||||
#: gtk/gtkmountoperation.c:711
|
||||
msgid "_Hidden"
|
||||
msgstr "_Oculto"
|
||||
|
||||
#: gtk/gtkmountoperation.c:714
|
||||
msgid "_Windows system"
|
||||
msgstr "Sistema _Windows"
|
||||
|
||||
#: gtk/gtkmountoperation.c:717
|
||||
msgid "_PIM"
|
||||
msgstr "_PIM"
|
||||
|
||||
#: gtk/gtkmountoperation.c:723
|
||||
msgid "_Password"
|
||||
msgstr "_Contraseña"
|
||||
|
||||
#: gtk/gtkmountoperation.c:671
|
||||
#: gtk/gtkmountoperation.c:745
|
||||
msgid "Forget password _immediately"
|
||||
msgstr "Olvidar contraseña _inmediatamente"
|
||||
|
||||
#: gtk/gtkmountoperation.c:681
|
||||
#: gtk/gtkmountoperation.c:755
|
||||
msgid "Remember password until you _logout"
|
||||
msgstr "Recordar la contraseña hasta _salir de la sesión"
|
||||
|
||||
#: gtk/gtkmountoperation.c:691
|
||||
#: gtk/gtkmountoperation.c:765
|
||||
msgid "Remember _forever"
|
||||
msgstr "_Recordar para siempre"
|
||||
|
||||
#: gtk/gtkmountoperation.c:1080
|
||||
#: gtk/gtkmountoperation.c:1160
|
||||
#, c-format
|
||||
msgid "Unknown Application (PID %d)"
|
||||
msgstr "Aplicación desconocida (PID %d)"
|
||||
|
||||
#: gtk/gtkmountoperation.c:1265
|
||||
#: gtk/gtkmountoperation.c:1345
|
||||
#, c-format
|
||||
msgid "Unable to end process"
|
||||
msgstr "No se pudo finalizar el proceso"
|
||||
|
||||
#: gtk/gtkmountoperation.c:1300
|
||||
#: gtk/gtkmountoperation.c:1380
|
||||
msgid "_End Process"
|
||||
msgstr "_Finalizar proceso"
|
||||
|
||||
@@ -2778,7 +2786,7 @@ msgstr "Configuración de página"
|
||||
msgid "Hide text"
|
||||
msgstr "Ocultar texto"
|
||||
|
||||
#: gtk/gtkpasswordentry.c:136 gtk/gtkpasswordentry.c:488
|
||||
#: gtk/gtkpasswordentry.c:136 gtk/gtkpasswordentry.c:483
|
||||
msgid "Show text"
|
||||
msgstr "Mostrar texto"
|
||||
|
||||
@@ -2786,11 +2794,11 @@ msgstr "Mostrar texto"
|
||||
msgid "Caps Lock is on"
|
||||
msgstr "Bloq Mayús está activado"
|
||||
|
||||
#: gtk/gtkpasswordentry.c:350
|
||||
#: gtk/gtkpasswordentry.c:344
|
||||
msgid "Password"
|
||||
msgstr "Contraseña"
|
||||
|
||||
#: gtk/gtkpasswordentry.c:562
|
||||
#: gtk/gtkpasswordentry.c:557
|
||||
msgid "_Show Text"
|
||||
msgstr "_Mostrar texto"
|
||||
|
||||
@@ -3087,11 +3095,11 @@ msgstr "_Conectar"
|
||||
msgid "Unable to get remote server location"
|
||||
msgstr "No se pudo obtener la ubicación del servidor remoto"
|
||||
|
||||
#: gtk/gtkplacesview.c:2026 gtk/gtkplacesview.c:2035
|
||||
#: gtk/gtkplacesview.c:2038 gtk/gtkplacesview.c:2047
|
||||
msgid "Networks"
|
||||
msgstr "Redes"
|
||||
|
||||
#: gtk/gtkplacesview.c:2026 gtk/gtkplacesview.c:2035
|
||||
#: gtk/gtkplacesview.c:2038 gtk/gtkplacesview.c:2047
|
||||
msgid "On This Computer"
|
||||
msgstr "En este equipo"
|
||||
|
||||
@@ -3358,7 +3366,7 @@ msgstr "De arriba a abajo"
|
||||
msgid "Bottom to top"
|
||||
msgstr "De abajo a arriba"
|
||||
|
||||
#: gtk/gtkprogressbar.c:626
|
||||
#: gtk/gtkprogressbar.c:613
|
||||
#, c-format
|
||||
msgctxt "progress bar label"
|
||||
msgid "%.0f %%"
|
||||
@@ -3472,7 +3480,7 @@ msgstr "No se han encontrado resultados"
|
||||
msgid "Try a different search"
|
||||
msgstr "Pruebe una búsqueda diferente"
|
||||
|
||||
#: gtk/gtktext.c:5782 gtk/gtktextview.c:8642
|
||||
#: gtk/gtktext.c:5795 gtk/gtktextview.c:8681
|
||||
msgid "Insert _Emoji"
|
||||
msgstr "Insertar _emoticono"
|
||||
|
||||
@@ -3539,24 +3547,24 @@ msgctxt "volume percentage"
|
||||
msgid "%d %%"
|
||||
msgstr "%d %%"
|
||||
|
||||
#: gtk/gtkwindow.c:6705
|
||||
#: gtk/gtkwindow.c:6721
|
||||
msgid "Move"
|
||||
msgstr "Mover"
|
||||
|
||||
#: gtk/gtkwindow.c:6713
|
||||
#: gtk/gtkwindow.c:6729
|
||||
msgid "Resize"
|
||||
msgstr "Redimensionar"
|
||||
|
||||
#: gtk/gtkwindow.c:6744
|
||||
#: gtk/gtkwindow.c:6760
|
||||
msgid "Always on Top"
|
||||
msgstr "Siempre encima"
|
||||
|
||||
#: gtk/gtkwindow.c:8997
|
||||
#: gtk/gtkwindow.c:9014
|
||||
#, c-format
|
||||
msgid "Do you want to use GTK Inspector?"
|
||||
msgstr "¿Quiere usar el inspector de GTK?"
|
||||
|
||||
#: gtk/gtkwindow.c:8999
|
||||
#: gtk/gtkwindow.c:9016
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK Inspector is an interactive debugger that lets you explore and modify "
|
||||
@@ -3567,7 +3575,7 @@ msgstr ""
|
||||
"modificar los aspectos internos de cualquier aplicación de GTK. Al usarlo "
|
||||
"puede hacer que la aplicación falle o se cierre."
|
||||
|
||||
#: gtk/gtkwindow.c:9004
|
||||
#: gtk/gtkwindow.c:9021
|
||||
msgid "Don’t show this message again"
|
||||
msgstr "No mostrar este mensaje de nuevo"
|
||||
|
||||
@@ -3665,25 +3673,25 @@ msgid "Show data"
|
||||
msgstr "Mostrar los datos"
|
||||
|
||||
# src/file-manager/fm-icon-text-window.c:85
|
||||
#: gtk/inspector/general.c:342
|
||||
#: gtk/inspector/general.c:343
|
||||
msgctxt "GL version"
|
||||
msgid "None"
|
||||
msgstr "Ninguna"
|
||||
|
||||
# src/file-manager/fm-icon-text-window.c:85
|
||||
#: gtk/inspector/general.c:343
|
||||
#: gtk/inspector/general.c:344
|
||||
msgctxt "GL vendor"
|
||||
msgid "None"
|
||||
msgstr "Ninguno"
|
||||
|
||||
# src/file-manager/fm-icon-text-window.c:85
|
||||
#: gtk/inspector/general.c:445
|
||||
#: gtk/inspector/general.c:446
|
||||
msgctxt "Vulkan device"
|
||||
msgid "None"
|
||||
msgstr "Ninguno"
|
||||
|
||||
# src/file-manager/fm-icon-text-window.c:85
|
||||
#: gtk/inspector/general.c:446 gtk/inspector/general.c:447
|
||||
#: gtk/inspector/general.c:447 gtk/inspector/general.c:448
|
||||
msgctxt "Vulkan version"
|
||||
msgid "None"
|
||||
msgstr "Ninguna"
|
||||
@@ -3700,39 +3708,43 @@ msgstr "«Backend» de GDK"
|
||||
msgid "GSK Renderer"
|
||||
msgstr "Renderizador GSK"
|
||||
|
||||
#: gtk/inspector/general.ui:118 gtk/ui/gtkplacesview.ui:77
|
||||
#: gtk/inspector/general.ui:108
|
||||
msgid "Pango Fontmap"
|
||||
msgstr "Mapa de tipografías de Pango"
|
||||
|
||||
#: gtk/inspector/general.ui:145 gtk/ui/gtkplacesview.ui:77
|
||||
msgid "Prefix"
|
||||
msgstr "Prefijo"
|
||||
|
||||
#: gtk/inspector/general.ui:324
|
||||
#: gtk/inspector/general.ui:351
|
||||
msgid "Display"
|
||||
msgstr "Pantalla"
|
||||
|
||||
#: gtk/inspector/general.ui:352
|
||||
#: gtk/inspector/general.ui:379
|
||||
msgid "RGBA Visual"
|
||||
msgstr "RGBA visual"
|
||||
|
||||
#: gtk/inspector/general.ui:379
|
||||
#: gtk/inspector/general.ui:406
|
||||
msgid "Composited"
|
||||
msgstr "Compuesta"
|
||||
|
||||
#: gtk/inspector/general.ui:416
|
||||
#: gtk/inspector/general.ui:443
|
||||
msgid "GL Version"
|
||||
msgstr "Versión de GL"
|
||||
|
||||
#: gtk/inspector/general.ui:444
|
||||
#: gtk/inspector/general.ui:471
|
||||
msgid "GL Vendor"
|
||||
msgstr "Fabricante GL"
|
||||
|
||||
#: gtk/inspector/general.ui:482
|
||||
#: gtk/inspector/general.ui:509
|
||||
msgid "Vulkan Device"
|
||||
msgstr "Dispositivo vulkan"
|
||||
|
||||
#: gtk/inspector/general.ui:510
|
||||
#: gtk/inspector/general.ui:537
|
||||
msgid "Vulkan API version"
|
||||
msgstr "Versión de la API Vulkan"
|
||||
|
||||
#: gtk/inspector/general.ui:538
|
||||
#: gtk/inspector/general.ui:565
|
||||
msgid "Vulkan driver version"
|
||||
msgstr "Versión del driver Vulkan"
|
||||
|
||||
@@ -7897,6 +7909,9 @@ msgstr "No hay un perfil disponible"
|
||||
msgid "Unspecified profile"
|
||||
msgstr "Perfil no especificado"
|
||||
|
||||
#~ msgid "Opening %s"
|
||||
#~ msgstr "Abriendo %s"
|
||||
|
||||
#~ msgid "C_ustomize"
|
||||
#~ msgstr "_Personalizar"
|
||||
|
||||
@@ -8195,10 +8210,6 @@ msgstr "Perfil no especificado"
|
||||
#~ msgid "Cyrillic (Transliterated)"
|
||||
#~ msgstr "Cirílico (Transliterado)"
|
||||
|
||||
#~ msgctxt "input method menu"
|
||||
#~ msgid "Windows IME"
|
||||
#~ msgstr "Windows IME"
|
||||
|
||||
#~ msgctxt "input method menu"
|
||||
#~ msgid "Inuktitut (Transliterated)"
|
||||
#~ msgstr "Inuktitut (Transliterado)"
|
||||
|
||||
@@ -5,9 +5,9 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gtk+ 0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2019-06-21 22:07+0000\n"
|
||||
"PO-Revision-Date: 2019-06-22 00:39+0200\n"
|
||||
"Last-Translator: gogo <trebelnik2@gmail.com>\n"
|
||||
"POT-Creation-Date: 2019-07-18 19:32+0000\n"
|
||||
"PO-Revision-Date: 2019-07-19 23:19+0200\n"
|
||||
"Last-Translator: gogo <linux.hr@protonmail.com>\n"
|
||||
"Language-Team: Croatian <lokalizacija@linux.hr>\n"
|
||||
"Language: hr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -876,15 +876,15 @@ msgctxt "Stock label"
|
||||
msgid "_Close"
|
||||
msgstr "_Zatvori"
|
||||
|
||||
#: gtk/a11y/gtkimageaccessible.c:60 gtk/gtkheaderbar.c:421 gtk/gtkwindow.c:6721
|
||||
#: gtk/a11y/gtkimageaccessible.c:60 gtk/gtkheaderbar.c:421 gtk/gtkwindow.c:6737
|
||||
msgid "Minimize"
|
||||
msgstr "Smanji"
|
||||
|
||||
#: gtk/a11y/gtkimageaccessible.c:61 gtk/gtkheaderbar.c:444 gtk/gtkwindow.c:6730
|
||||
#: gtk/a11y/gtkimageaccessible.c:61 gtk/gtkheaderbar.c:444 gtk/gtkwindow.c:6746
|
||||
msgid "Maximize"
|
||||
msgstr "Uvećaj"
|
||||
|
||||
#: gtk/a11y/gtkimageaccessible.c:62 gtk/gtkheaderbar.c:444 gtk/gtkwindow.c:6687
|
||||
#: gtk/a11y/gtkimageaccessible.c:62 gtk/gtkheaderbar.c:444 gtk/gtkwindow.c:6703
|
||||
msgid "Restore"
|
||||
msgstr "Vrati"
|
||||
|
||||
@@ -1870,19 +1870,19 @@ msgid "White"
|
||||
msgstr "Bijela"
|
||||
|
||||
#. translators: label for the custom section in the color chooser
|
||||
#: gtk/gtkcolorchooserwidget.c:551
|
||||
#: gtk/gtkcolorchooserwidget.c:549
|
||||
msgid "Custom"
|
||||
msgstr "Prilagođena"
|
||||
|
||||
#: gtk/gtkcolorchooserwidget.c:562
|
||||
#: gtk/gtkcolorchooserwidget.c:560
|
||||
msgid "Custom color"
|
||||
msgstr "Prilagođena boja"
|
||||
|
||||
#: gtk/gtkcolorchooserwidget.c:563
|
||||
#: gtk/gtkcolorchooserwidget.c:561
|
||||
msgid "Create a custom color"
|
||||
msgstr "Stvori prilagođenu boju"
|
||||
|
||||
#: gtk/gtkcolorchooserwidget.c:582
|
||||
#: gtk/gtkcolorchooserwidget.c:580
|
||||
#, c-format
|
||||
msgid "Custom color %d: %s"
|
||||
msgstr "Prilagođena boja %d: %s"
|
||||
@@ -1901,7 +1901,7 @@ msgctxt "Color channel"
|
||||
msgid "Alpha"
|
||||
msgstr "Alfa"
|
||||
|
||||
#: gtk/gtkcolorswatch.c:289
|
||||
#: gtk/gtkcolorswatch.c:287
|
||||
msgid "Customize"
|
||||
msgstr "Prilagodi"
|
||||
|
||||
@@ -2050,12 +2050,12 @@ msgid "A file with that name already exists"
|
||||
msgstr "Datoteka s tim nazivom već postoji"
|
||||
|
||||
#: gtk/gtkfilechoosernative.c:525 gtk/gtkfilechoosernative.c:603
|
||||
#: gtk/gtkfilechooserwidget.c:1450 gtk/gtkfilechooserwidget.c:6150
|
||||
#: gtk/gtkfilechooserwidget.c:1464 gtk/gtkfilechooserwidget.c:6322
|
||||
#: gtk/gtkmessagedialog.c:791 gtk/gtkmessagedialog.c:800
|
||||
#: gtk/gtkmountoperation.c:543 gtk/gtkpagesetupunixdialog.c:210
|
||||
#: gtk/gtkprintbackend.c:657 gtk/gtkprinteroptionwidget.c:545
|
||||
#: gtk/gtkprintunixdialog.c:680 gtk/gtkprintunixdialog.c:746
|
||||
#: gtk/gtkwindow.c:9009 gtk/inspector/css-editor.c:237
|
||||
#: gtk/gtkwindow.c:9025 gtk/inspector/css-editor.c:237
|
||||
#: gtk/inspector/recorder.c:1026 gtk/ui/gtkappchooserdialog.ui:46
|
||||
#: gtk/ui/gtkassistant.ui:50 gtk/ui/gtkcolorchooserdialog.ui:28
|
||||
#: gtk/ui/gtkfontchooserdialog.ui:22
|
||||
@@ -2074,7 +2074,7 @@ msgstr "_Otvori"
|
||||
msgid "_Save"
|
||||
msgstr "_Spremi"
|
||||
|
||||
#: gtk/gtkfilechoosernativequartz.c:331 gtk/ui/gtkfilechooserwidget.ui:350
|
||||
#: gtk/gtkfilechoosernativequartz.c:331 gtk/ui/gtkfilechooserwidget.ui:362
|
||||
msgid "Select which types of files are shown"
|
||||
msgstr "Odaberi koje vrste datoteka se prikazuju"
|
||||
|
||||
@@ -2087,15 +2087,15 @@ msgstr "Odaberi koje vrste datoteka se prikazuju"
|
||||
msgid "%1$s on %2$s"
|
||||
msgstr "%1$s na %2$s"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:381
|
||||
#: gtk/gtkfilechooserwidget.c:393
|
||||
msgid "Type name of new folder"
|
||||
msgstr "Upišite naziv nove mape"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:773
|
||||
#: gtk/gtkfilechooserwidget.c:787
|
||||
msgid "The folder could not be created"
|
||||
msgstr "Mapa nije mogla biti stvorena"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:786
|
||||
#: gtk/gtkfilechooserwidget.c:800
|
||||
msgid ""
|
||||
"The folder could not be created, as a file with the same name already "
|
||||
"exists. Try using a different name for the folder, or rename the file first."
|
||||
@@ -2103,213 +2103,271 @@ msgstr ""
|
||||
"Mapa nije mogla biti stvorena, jer već postoji datoteka s istim nazivom. "
|
||||
"Pokušajte koristiti drugi naziv za mapu, ili prvo preimenujte datoteku."
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:801
|
||||
#: gtk/gtkfilechooserwidget.c:815
|
||||
msgid "You need to choose a valid filename."
|
||||
msgstr "Morate odabrati valjani naziv datoteke."
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:804
|
||||
#: gtk/gtkfilechooserwidget.c:818
|
||||
#, c-format
|
||||
msgid "Cannot create a file under %s as it is not a folder"
|
||||
msgstr "Nemoguće stvaranje datoteke unutar %s pošto nije mapa"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:814
|
||||
#: gtk/gtkfilechooserwidget.c:828
|
||||
msgid "Cannot create file as the filename is too long"
|
||||
msgstr "Nemoguće stvaranje datoteke je je naziv predugačak"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:815
|
||||
#: gtk/gtkfilechooserwidget.c:829
|
||||
msgid "Try using a shorter name."
|
||||
msgstr "Pokušajte koristiti kraći naziv."
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:825
|
||||
#: gtk/gtkfilechooserwidget.c:839
|
||||
msgid "You may only select folders"
|
||||
msgstr "Možete odabrati samo mape"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:826
|
||||
#: gtk/gtkfilechooserwidget.c:840
|
||||
msgid "The item that you selected is not a folder try using a different item."
|
||||
msgstr "Stavka koju ste odabrali nije mapa, pokušajte odabrati drugu stavku."
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:834
|
||||
#: gtk/gtkfilechooserwidget.c:848
|
||||
msgid "Invalid file name"
|
||||
msgstr "Neispravni naziv datoteke"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:843
|
||||
#: gtk/gtkfilechooserwidget.c:857
|
||||
msgid "The folder contents could not be displayed"
|
||||
msgstr "Sadržaj mape nije mogao biti prikazan"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:851
|
||||
#: gtk/gtkfilechooserwidget.c:865
|
||||
msgid "The file could not be deleted"
|
||||
msgstr "Datoteku je nemoguće obrisati"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:859
|
||||
#: gtk/gtkfilechooserwidget.c:873
|
||||
msgid "The file could not be moved to the Trash"
|
||||
msgstr "Datoteka se ne može premjestiti u smeće"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:1446
|
||||
#: gtk/gtkfilechooserwidget.c:1460
|
||||
#, c-format
|
||||
msgid "Are you sure you want to permanently delete “%s”?"
|
||||
msgstr "Sigurno želite trajno obrisati “%s”?"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:1449
|
||||
#: gtk/gtkfilechooserwidget.c:1463
|
||||
#, c-format
|
||||
msgid "If you delete an item, it will be permanently lost."
|
||||
msgstr "Ako obrišete stavku, biti će trajno izgubljena."
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:1451 gtk/gtkfilechooserwidget.c:2168
|
||||
#: gtk/gtklabel.c:6096 gtk/gtktext.c:5810 gtk/gtktextview.c:8629
|
||||
#: gtk/gtkfilechooserwidget.c:1465 gtk/gtkfilechooserwidget.c:2199
|
||||
#: gtk/gtklabel.c:6096 gtk/gtktext.c:5772 gtk/gtktextview.c:8628
|
||||
msgid "_Delete"
|
||||
msgstr "_Obriši"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:1578
|
||||
#: gtk/gtkfilechooserwidget.c:1592
|
||||
msgid "The file could not be renamed"
|
||||
msgstr "Datoteka ne može biti preimenovana"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:1820
|
||||
#: gtk/gtkfilechooserwidget.c:1850
|
||||
msgid "Could not select file"
|
||||
msgstr "Nemoguć odabir datoteke"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:2163
|
||||
#: gtk/gtkfilechooserwidget.c:2194
|
||||
msgid "_Visit File"
|
||||
msgstr "_Posjeti datoteku"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:2164
|
||||
#: gtk/gtkfilechooserwidget.c:2195
|
||||
msgid "_Open With File Manager"
|
||||
msgstr "_Otvori s preglednikom datoteka"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:2165
|
||||
#: gtk/gtkfilechooserwidget.c:2196
|
||||
msgid "_Copy Location"
|
||||
msgstr "_Kopiraj lokaciju"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:2166
|
||||
#: gtk/gtkfilechooserwidget.c:2197
|
||||
msgid "_Add to Bookmarks"
|
||||
msgstr "_Dodaj u zabilješke"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:2167 gtk/gtkplacessidebar.c:2690
|
||||
#: gtk/ui/gtkfilechooserwidget.ui:470
|
||||
#: gtk/gtkfilechooserwidget.c:2198 gtk/gtkplacessidebar.c:2690
|
||||
#: gtk/ui/gtkfilechooserwidget.ui:482
|
||||
msgid "_Rename"
|
||||
msgstr "_Preimenuj"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:2169
|
||||
#: gtk/gtkfilechooserwidget.c:2200
|
||||
msgid "_Move to Trash"
|
||||
msgstr "_Premjesti u smeće"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:2173
|
||||
#: gtk/gtkfilechooserwidget.c:2204
|
||||
msgid "Show _Hidden Files"
|
||||
msgstr "Prikaži _skrivene datoteke"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:2174
|
||||
#: gtk/gtkfilechooserwidget.c:2205
|
||||
msgid "Show _Size Column"
|
||||
msgstr "Prikaži _stupac veličine"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:2175
|
||||
#: gtk/gtkfilechooserwidget.c:2206
|
||||
msgid "Show T_ype Column"
|
||||
msgstr "Prikaži s_tupac vrste"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:2207
|
||||
msgid "Show _Time"
|
||||
msgstr "Prikaži _vrijeme"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:2176
|
||||
#: gtk/gtkfilechooserwidget.c:2208
|
||||
msgid "Sort _Folders before Files"
|
||||
msgstr "Poredaj _mape prije datoteka"
|
||||
|
||||
#. this is the header for the location column in the print dialog
|
||||
#: gtk/gtkfilechooserwidget.c:2473 gtk/inspector/css-node-tree.ui:133
|
||||
#: gtk/gtkfilechooserwidget.c:2509 gtk/inspector/css-node-tree.ui:133
|
||||
#: gtk/ui/gtkfilechooserwidget.ui:194 gtk/ui/gtkprintunixdialog.ui:108
|
||||
msgid "Location"
|
||||
msgstr "Lokacija"
|
||||
|
||||
#. Label
|
||||
#: gtk/gtkfilechooserwidget.c:2566
|
||||
#: gtk/gtkfilechooserwidget.c:2602
|
||||
msgid "_Name:"
|
||||
msgstr "_Naziv:"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:3190 gtk/gtkfilechooserwidget.c:3204
|
||||
#: gtk/gtkfilechooserwidget.c:3226 gtk/gtkfilechooserwidget.c:3240
|
||||
#, c-format
|
||||
msgid "Searching in %s"
|
||||
msgstr "Pretražujem u %s"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:3210
|
||||
#: gtk/gtkfilechooserwidget.c:3246
|
||||
msgid "Searching"
|
||||
msgstr "Pretraživanje"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:3217
|
||||
#: gtk/gtkfilechooserwidget.c:3253
|
||||
msgid "Enter location"
|
||||
msgstr "Upiši lokaciju"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:3219
|
||||
#: gtk/gtkfilechooserwidget.c:3255
|
||||
msgid "Enter location or URL"
|
||||
msgstr "Upiši URL lokacije"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4185 gtk/gtkfilechooserwidget.c:7059
|
||||
#: gtk/ui/gtkfilechooserwidget.ui:222
|
||||
#: gtk/gtkfilechooserwidget.c:4263 gtk/gtkfilechooserwidget.c:7232
|
||||
#: gtk/ui/gtkfilechooserwidget.ui:234
|
||||
msgid "Modified"
|
||||
msgstr "Mijenjano"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4463
|
||||
#: gtk/gtkfilechooserwidget.c:4541
|
||||
#, c-format
|
||||
msgid "Could not read the contents of %s"
|
||||
msgstr "Nemoguće pročitati sadržaj %s"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4467
|
||||
#: gtk/gtkfilechooserwidget.c:4545
|
||||
msgid "Could not read the contents of the folder"
|
||||
msgstr "Nemoguće čitanje sadržaja mape"
|
||||
|
||||
#. Translators: see g_date_time_format() for details on the format
|
||||
#: gtk/gtkfilechooserwidget.c:4592 gtk/gtkfilechooserwidget.c:4636
|
||||
#: gtk/gtkfilechooserwidget.c:4670 gtk/gtkfilechooserwidget.c:4714
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4594 gtk/gtkfilechooserwidget.c:4638
|
||||
#: gtk/gtkfilechooserwidget.c:4672 gtk/gtkfilechooserwidget.c:4716
|
||||
msgid "%l:%M %p"
|
||||
msgstr "%l:%M %p"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4598
|
||||
#: gtk/gtkfilechooserwidget.c:4676
|
||||
msgid "Yesterday"
|
||||
msgstr "Jučer"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4606
|
||||
#: gtk/gtkfilechooserwidget.c:4684
|
||||
msgid "%-e %b"
|
||||
msgstr "%-e %b"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4610
|
||||
#: gtk/gtkfilechooserwidget.c:4688
|
||||
msgid "%-e %b %Y"
|
||||
msgstr "%-e %b %Y"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4778 gtk/gtkfilechooserwidget.c:4786
|
||||
msgid "Program"
|
||||
msgstr "Program"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4779
|
||||
msgid "Audio"
|
||||
msgstr "Zvuk"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4780 gtk/gtkfontbutton.c:611
|
||||
#: gtk/inspector/visual.ui:187
|
||||
msgid "Font"
|
||||
msgstr "Slova"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4781
|
||||
msgid "Image"
|
||||
msgstr "Slika"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4782
|
||||
msgid "Archive"
|
||||
msgstr "Arhiva"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4783
|
||||
msgid "Markup"
|
||||
msgstr "Oznaka"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4784 gtk/gtkfilechooserwidget.c:4785
|
||||
msgid "Text"
|
||||
msgstr "Tekst"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4787
|
||||
msgid "Video"
|
||||
msgstr "Video snimka"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4788
|
||||
msgid "Contacts"
|
||||
msgstr "Kontakti"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4789
|
||||
msgid "Calendar"
|
||||
msgstr "Kalendar"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4790
|
||||
msgid "Document"
|
||||
msgstr "Dokument"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4791
|
||||
msgid "Presentation"
|
||||
msgstr "Prezentacija"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4792
|
||||
msgid "Spreadsheet"
|
||||
msgstr "Proračunska tablica"
|
||||
|
||||
#. Translators: We don't know whether this printer is
|
||||
#. * available to print to.
|
||||
#: gtk/gtkfilechooserwidget.c:4836 gtk/inspector/prop-editor.c:1506
|
||||
#: gtk/gtkfilechooserwidget.c:4823 gtk/gtkfilechooserwidget.c:5007
|
||||
#: gtk/inspector/prop-editor.c:1506
|
||||
#: modules/printbackends/gtkprintbackendcloudprint.c:731
|
||||
msgid "Unknown"
|
||||
msgstr "Nepoznato"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:4875 gtk/gtkplacessidebar.c:1087
|
||||
#: gtk/gtkfilechooserwidget.c:5046 gtk/gtkplacessidebar.c:1087
|
||||
msgid "Home"
|
||||
msgstr "Osobna mapa"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:5368
|
||||
#: gtk/gtkfilechooserwidget.c:5540
|
||||
msgid "Cannot change to folder because it is not local"
|
||||
msgstr "Nemoguća promjena u mapu jer nije na lokalnom računalu"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:6143 gtk/gtkprintunixdialog.c:671
|
||||
#: gtk/gtkfilechooserwidget.c:6315 gtk/gtkprintunixdialog.c:671
|
||||
#, c-format
|
||||
msgid "A file named “%s” already exists. Do you want to replace it?"
|
||||
msgstr "Datoteka naziva “%s” već postoji. Želite li ju zamijeniti?"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:6146 gtk/gtkprintunixdialog.c:675
|
||||
#: gtk/gtkfilechooserwidget.c:6318 gtk/gtkprintunixdialog.c:675
|
||||
#, c-format
|
||||
msgid ""
|
||||
"The file already exists in “%s”. Replacing it will overwrite its contents."
|
||||
msgstr "Datoteka već postoji u “%s”. Zamjena će prebrisati sav njen sadržaj."
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:6151 gtk/gtkprintunixdialog.c:683
|
||||
#: gtk/gtkfilechooserwidget.c:6323 gtk/gtkprintunixdialog.c:683
|
||||
msgid "_Replace"
|
||||
msgstr "_Zamijeni"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:6359
|
||||
#: gtk/gtkfilechooserwidget.c:6531
|
||||
msgid "You do not have access to the specified folder."
|
||||
msgstr "Ne možete pristupiti određenoj mapi."
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:6983
|
||||
#: gtk/gtkfilechooserwidget.c:7155
|
||||
msgid "Could not send the search request"
|
||||
msgstr "Nemoguće slanje zahtjeva pretrage"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:7276
|
||||
#: gtk/gtkfilechooserwidget.c:7450
|
||||
msgid "Accessed"
|
||||
msgstr "Pristupljeno"
|
||||
|
||||
@@ -2330,10 +2388,6 @@ msgstr "Sans 12"
|
||||
msgid "Pick a Font"
|
||||
msgstr "Odaberi slova"
|
||||
|
||||
#: gtk/gtkfontbutton.c:611 gtk/inspector/visual.ui:187
|
||||
msgid "Font"
|
||||
msgstr "Slova"
|
||||
|
||||
#: gtk/gtkfontbutton.c:1329
|
||||
msgctxt "font"
|
||||
msgid "None"
|
||||
@@ -2395,7 +2449,7 @@ msgstr "Neuspjelo stvaranje OpenGL sadržaja"
|
||||
msgid "Application menu"
|
||||
msgstr "Izbornik aplikacije"
|
||||
|
||||
#: gtk/gtkheaderbar.c:462 gtk/gtkwindow.c:6757
|
||||
#: gtk/gtkheaderbar.c:462 gtk/gtkwindow.c:6773
|
||||
msgid "Close"
|
||||
msgstr "Zatvori"
|
||||
|
||||
@@ -2424,19 +2478,19 @@ msgstr "Upozorenje"
|
||||
msgid "Error"
|
||||
msgstr "Greška"
|
||||
|
||||
#: gtk/gtklabel.c:6093 gtk/gtktext.c:5798 gtk/gtktextview.c:8617
|
||||
#: gtk/gtklabel.c:6093 gtk/gtktext.c:5760 gtk/gtktextview.c:8616
|
||||
msgid "Cu_t"
|
||||
msgstr "Iz_reži"
|
||||
|
||||
#: gtk/gtklabel.c:6094 gtk/gtktext.c:5802 gtk/gtktextview.c:8621
|
||||
#: gtk/gtklabel.c:6094 gtk/gtktext.c:5764 gtk/gtktextview.c:8620
|
||||
msgid "_Copy"
|
||||
msgstr "_Kopiraj"
|
||||
|
||||
#: gtk/gtklabel.c:6095 gtk/gtktext.c:5806 gtk/gtktextview.c:8625
|
||||
#: gtk/gtklabel.c:6095 gtk/gtktext.c:5768 gtk/gtktextview.c:8624
|
||||
msgid "_Paste"
|
||||
msgstr "_Zalijepi"
|
||||
|
||||
#: gtk/gtklabel.c:6101 gtk/gtktext.c:5819 gtk/gtktextview.c:8638
|
||||
#: gtk/gtklabel.c:6101 gtk/gtktext.c:5781 gtk/gtktextview.c:8637
|
||||
msgid "Select _All"
|
||||
msgstr "Odaberi _sve"
|
||||
|
||||
@@ -2493,7 +2547,7 @@ msgstr ""
|
||||
#. * Do *not* translate it to "predefinito:LTR", if it
|
||||
#. * it isn't default:LTR or default:RTL it will not work
|
||||
#.
|
||||
#: gtk/gtkmain.c:976
|
||||
#: gtk/gtkmain.c:977
|
||||
msgid "default:LTR"
|
||||
msgstr "default:LTR"
|
||||
|
||||
@@ -2546,7 +2600,7 @@ msgid "%d:%02d"
|
||||
msgstr "%d:%02d"
|
||||
|
||||
#: gtk/gtkmessagedialog.c:783 gtk/gtkmessagedialog.c:801
|
||||
#: gtk/gtkprintbackend.c:658 gtk/gtkwindow.c:9010
|
||||
#: gtk/gtkprintbackend.c:658 gtk/gtkwindow.c:9026
|
||||
msgid "_OK"
|
||||
msgstr "_U redu"
|
||||
|
||||
@@ -2598,17 +2652,17 @@ msgstr "Zapamti lozinku do _odjave"
|
||||
msgid "Remember _forever"
|
||||
msgstr "Zapamti _zauvijek"
|
||||
|
||||
#: gtk/gtkmountoperation.c:1080
|
||||
#: gtk/gtkmountoperation.c:1086
|
||||
#, c-format
|
||||
msgid "Unknown Application (PID %d)"
|
||||
msgstr "Nepoznata aplikacija (PID %d)"
|
||||
|
||||
#: gtk/gtkmountoperation.c:1265
|
||||
#: gtk/gtkmountoperation.c:1271
|
||||
#, c-format
|
||||
msgid "Unable to end process"
|
||||
msgstr "Nemoguće zaustavljanje procesa"
|
||||
|
||||
#: gtk/gtkmountoperation.c:1300
|
||||
#: gtk/gtkmountoperation.c:1306
|
||||
msgid "_End Process"
|
||||
msgstr "_Zaustavi proces"
|
||||
|
||||
@@ -2855,7 +2909,7 @@ msgstr "Ovaj naziv se već koristi"
|
||||
|
||||
#: gtk/gtkplacessidebar.c:2684 gtk/inspector/actions.ui:25
|
||||
#: gtk/inspector/css-node-tree.ui:34 gtk/ui/gtkfilechooserwidget.ui:176
|
||||
#: gtk/ui/gtkfilechooserwidget.ui:445
|
||||
#: gtk/ui/gtkfilechooserwidget.ui:457
|
||||
msgid "Name"
|
||||
msgstr "Naziv"
|
||||
|
||||
@@ -3279,7 +3333,7 @@ msgstr "S vrha nadno"
|
||||
msgid "Bottom to top"
|
||||
msgstr "S dna na vrh"
|
||||
|
||||
#: gtk/gtkprogressbar.c:626
|
||||
#: gtk/gtkprogressbar.c:613
|
||||
#, c-format
|
||||
msgctxt "progress bar label"
|
||||
msgid "%.0f %%"
|
||||
@@ -3384,16 +3438,16 @@ msgid "Search Shortcuts"
|
||||
msgstr "Prečaci pretrage"
|
||||
|
||||
#: gtk/gtkshortcutswindow.c:1011 gtk/ui/gtkemojichooser.ui:322
|
||||
#: gtk/ui/gtkfilechooserwidget.ui:294
|
||||
#: gtk/ui/gtkfilechooserwidget.ui:306
|
||||
msgid "No Results Found"
|
||||
msgstr "Nema pronađenih rezultata"
|
||||
|
||||
#: gtk/gtkshortcutswindow.c:1017 gtk/ui/gtkemojichooser.ui:335
|
||||
#: gtk/ui/gtkfilechooserwidget.ui:307 gtk/ui/gtkplacesview.ui:235
|
||||
#: gtk/ui/gtkfilechooserwidget.ui:319 gtk/ui/gtkplacesview.ui:235
|
||||
msgid "Try a different search"
|
||||
msgstr "Pokušaj drugačiju pretragu"
|
||||
|
||||
#: gtk/gtktext.c:5824 gtk/gtktextview.c:8643
|
||||
#: gtk/gtktext.c:5786 gtk/gtktextview.c:8642
|
||||
msgid "Insert _Emoji"
|
||||
msgstr "Umetni _smajli"
|
||||
|
||||
@@ -3460,24 +3514,24 @@ msgctxt "volume percentage"
|
||||
msgid "%d %%"
|
||||
msgstr "%d %%"
|
||||
|
||||
#: gtk/gtkwindow.c:6705
|
||||
#: gtk/gtkwindow.c:6721
|
||||
msgid "Move"
|
||||
msgstr "Pomakni"
|
||||
|
||||
#: gtk/gtkwindow.c:6713
|
||||
#: gtk/gtkwindow.c:6729
|
||||
msgid "Resize"
|
||||
msgstr "Promijeni veličinu"
|
||||
|
||||
#: gtk/gtkwindow.c:6744
|
||||
#: gtk/gtkwindow.c:6760
|
||||
msgid "Always on Top"
|
||||
msgstr "Uvijek na vrhu"
|
||||
|
||||
#: gtk/gtkwindow.c:8997
|
||||
#: gtk/gtkwindow.c:9013
|
||||
#, c-format
|
||||
msgid "Do you want to use GTK Inspector?"
|
||||
msgstr "Želite li koristiti GTK Inspektora?"
|
||||
|
||||
#: gtk/gtkwindow.c:8999
|
||||
#: gtk/gtkwindow.c:9015
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK Inspector is an interactive debugger that lets you explore and modify "
|
||||
@@ -3488,7 +3542,7 @@ msgstr ""
|
||||
"otkrivanje i promjenu unutrašnjosti bilo koje GTK aplikacije. Njegovo "
|
||||
"korištenje može uzrokovati rušenje ili prekid u radu aplikacije."
|
||||
|
||||
#: gtk/gtkwindow.c:9004
|
||||
#: gtk/gtkwindow.c:9020
|
||||
msgid "Don’t show this message again"
|
||||
msgstr "Ne prikazuj više ovu poruku"
|
||||
|
||||
@@ -3676,6 +3730,7 @@ msgid "Address"
|
||||
msgstr "Adresa"
|
||||
|
||||
#: gtk/inspector/misc-info.ui:56 gtk/inspector/statistics.ui:45
|
||||
#: gtk/ui/gtkfilechooserwidget.ui:222
|
||||
msgid "Type"
|
||||
msgstr "Vrsta"
|
||||
|
||||
@@ -6861,15 +6916,15 @@ msgstr "Stvori mapu"
|
||||
msgid "Files"
|
||||
msgstr "Datoteke"
|
||||
|
||||
#: gtk/ui/gtkfilechooserwidget.ui:245
|
||||
#: gtk/ui/gtkfilechooserwidget.ui:257
|
||||
msgid "Remote location — only searching the current folder"
|
||||
msgstr "Udaljena lokacija — samo pretraži trenutnu mapu"
|
||||
|
||||
#: gtk/ui/gtkfilechooserwidget.ui:385
|
||||
#: gtk/ui/gtkfilechooserwidget.ui:397
|
||||
msgid "Folder Name"
|
||||
msgstr "Naziv mape"
|
||||
|
||||
#: gtk/ui/gtkfilechooserwidget.ui:411
|
||||
#: gtk/ui/gtkfilechooserwidget.ui:423
|
||||
msgid "_Create"
|
||||
msgstr "_Stvori"
|
||||
|
||||
@@ -7901,9 +7956,6 @@ msgstr "Neodređeni profil"
|
||||
#~ msgid "Similar"
|
||||
#~ msgstr "Slično"
|
||||
|
||||
#~ msgid "Image"
|
||||
#~ msgstr "Slika"
|
||||
|
||||
#~ msgid "GL Rendering"
|
||||
#~ msgstr "GL prikazivanje"
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user