/* GTK - The GIMP Toolkit
* Copyright ( C ) 2011 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 "gtkprivate.h"
#include "gtkcssvalueprivate.h"
#include "gtkcssstyleprivate.h"
#include "gtkstyleproviderprivate.h"
struct _GtkCssValue {
GTK_CSS_VALUE_BASE
};
G_DEFINE_BOXED_TYPE (GtkCssValue, gtk_css_value, gtk_css_value_ref, gtk_css_value_unref)
#undef CSS_VALUE_ACCOUNTING
#ifdef CSS_VALUE_ACCOUNTING
static GHashTable *counters;
typedef struct
{
guint all;
guint alive;
guint computed;
guint transitioned;
} ValueAccounting;
static void
dump_value_counts (void )
{
int col_widths[5 ] = { 0 , strlen ("all" ), strlen ("alive" ), strlen ("computed" ), strlen("transitioned" ) };
GHashTableIter iter;
gpointer key;
gpointer value;
int sum_all = 0 , sum_alive = 0 , sum_computed = 0 , sum_transitioned = 0 ;
g_hash_table_iter_init (&iter, counters);
while (g_hash_table_iter_next (&iter, &key, &value))
{
const char *class = key;
const ValueAccounting *c = value;
char *str;
sum_all += c->all;
sum_alive += c->alive;
sum_computed += c->computed;
sum_transitioned += c->transitioned;
col_widths[0 ] = MAX (col_widths[0 ], strlen (class ));
str = g_strdup_printf ("%'d" , sum_all);
col_widths[1 ] = MAX (col_widths[1 ], strlen (str));
g_free (str);
str = g_strdup_printf ("%'d" , sum_alive);
col_widths[2 ] = MAX (col_widths[2 ], strlen (str));
g_free (str);
str = g_strdup_printf ("%'d" , sum_computed);
col_widths[3 ] = MAX (col_widths[3 ], strlen (str));
g_free (str);
str = g_strdup_printf ("%'d" , sum_transitioned);
col_widths[4 ] = MAX (col_widths[4 ], strlen (str));
g_free (str);
}
/* Some spacing */
col_widths[0 ] += 4 ;
col_widths[1 ] += 4 ;
col_widths[2 ] += 4 ;
col_widths[3 ] += 4 ;
col_widths[4 ] += 4 ;
g_print("%*s%*s%*s%*s%*s\n" , col_widths[0 ] + 1 , " " ,
col_widths[1 ] + 1 , "All" ,
col_widths[2 ] + 1 , "Alive" ,
col_widths[3 ] + 1 , "Computed" ,
col_widths[4 ] + 1 , "Transitioned" );
g_hash_table_iter_init (&iter, counters);
while (g_hash_table_iter_next (&iter, &key, &value))
{
const char *class = key;
const ValueAccounting *c = value;
g_print ("%*s:" , col_widths[0 ], class );
g_print (" %'*d" , col_widths[1 ], c->all);
g_print (" %'*d" , col_widths[2 ], c->alive);
g_print (" %'*d" , col_widths[3 ], c->computed);
g_print (" %'*d" , col_widths[4 ], c->transitioned);
g_print("\n" );
}
g_print("%*s%'*d%'*d%'*d%'*d\n" , col_widths[0 ] + 1 , " " ,
col_widths[1 ] + 1 , sum_all,
col_widths[2 ] + 1 , sum_alive,
col_widths[3 ] + 1 , sum_computed,
col_widths[4 ] + 1 , sum_transitioned);
}
static ValueAccounting *
get_accounting_data (const char *class )
{
ValueAccounting *c;
if (!counters)
{
counters = g_hash_table_new (g_str_hash, g_str_equal);
atexit (dump_value_counts);
}
c = g_hash_table_lookup (counters, class );
if (!c)
{
c = g_new0 (ValueAccounting, 1 );
g_hash_table_insert (counters, (gpointer)class , c);
}
return c;
}
#endif
GtkCssValue *
gtk_css_value_alloc (const GtkCssValueClass *klass,
gsize size)
{
GtkCssValue *value;
value = g_malloc0 (size);
value->class = klass;
value->ref_count = 1 ;
#ifdef CSS_VALUE_ACCOUNTING
{
ValueAccounting *c;
c = get_accounting_data (klass->type_name);
c->all++;
c->alive++;
}
#endif
return value;
}
GtkCssValue *
(gtk_css_value_ref) (GtkCssValue *value)
{
gtk_internal_return_val_if_fail (value != NULL, NULL);
value->ref_count += 1 ;
return value;
}
void
(gtk_css_value_unref) (GtkCssValue *value)
{
if (value == NULL)
return ;
value->ref_count -= 1 ;
if (value->ref_count > 0 )
return ;
#ifdef CSS_VALUE_ACCOUNTING
{
ValueAccounting *c;
c = get_accounting_data (value->class ->type_name);
c->alive--;
}
#endif
value->class ->free (value);
}
/**
* gtk_css_value_compute :
* @ value : the value to compute from
* @ property_id : the ID of the property to compute
* @ context : the context containing the style provider , style
* parent style and variables that might be used during computation
*
* Converts the specified @ value into the computed value for the CSS
* property given by @ property_id using the information in @ context .
* This step is explained in detail in the
* [ CSS Documentation ] ( http : //www.w3.org/TR/css3-cascade/#computed).
*
* Returns : the computed value
**/
GtkCssValue *
gtk_css_value_compute (GtkCssValue *value,
guint property_id,
GtkCssComputeContext *context)
{
if (gtk_css_value_is_computed (value))
return gtk_css_value_ref (value);
#ifdef CSS_VALUE_ACCOUNTING
get_accounting_data (value->class ->type_name)->computed++;
#endif
return value->class ->compute (value, property_id, context);
}
/**
* gtk_css_value_resolve :
* @ value : the value to resolve
* @ context : the context containing the style provider , style
* parent style and variables that might be used during computation
* @ current_color : the value to use for currentcolor
*
* Converts the computed @ value into the used value , by replacing
* currentcolor with @ current_color .
*
* Returns : the used value
*/
GtkCssValue *
gtk_css_value_resolve (GtkCssValue *value,
GtkCssComputeContext *context,
GtkCssValue *current_color)
{
if (!gtk_css_value_contains_current_color (value))
return gtk_css_value_ref (value);
if (!value->class ->resolve)
return gtk_css_value_ref (value);
return value->class ->resolve (value, context, current_color);
}
gboolean
gtk_css_value_equal (const GtkCssValue *value1,
const GtkCssValue *value2)
{
gtk_internal_return_val_if_fail (value1 != NULL, FALSE );
gtk_internal_return_val_if_fail (value2 != NULL, FALSE );
if (value1 == value2)
return TRUE ;
if (value1->class != value2->class )
return FALSE ;
return value1->class ->equal (value1, value2);
}
gboolean
gtk_css_value_equal0 (const GtkCssValue *value1,
const GtkCssValue *value2)
{
/* Includes both values being NULL */
if (value1 == value2)
return TRUE ;
if (value1 == NULL || value2 == NULL)
return FALSE ;
return gtk_css_value_equal (value1, value2);
}
GtkCssValue *
gtk_css_value_transition (GtkCssValue *start,
GtkCssValue *end,
guint property_id,
double progress)
{
gtk_internal_return_val_if_fail (start != NULL, NULL);
gtk_internal_return_val_if_fail (end != NULL, NULL);
if (start->class != end->class )
return NULL;
if (progress == 0 )
return gtk_css_value_ref (start);
if (progress == 1 )
return gtk_css_value_ref (end);
if (start == end)
return gtk_css_value_ref (start);
#ifdef CSS_VALUE_ACCOUNTING
get_accounting_data (start->class ->type_name)->transitioned++;
#endif
return start->class ->transition (start, end, property_id, progress);
}
char *
gtk_css_value_to_string (const GtkCssValue *value)
{
GString *string;
gtk_internal_return_val_if_fail (value != NULL, NULL);
string = g_string_new (NULL);
gtk_css_value_print (value, string);
return g_string_free (string, FALSE );
}
/**
* gtk_css_value_print :
* @ value : the value to print
* @ string : the string to print to
*
* Prints @ value to the given @ string in CSS format . The @ value must be a
* valid specified value as parsed using the parse functions or as assigned
* via _ gtk_style_property_assign ( ) .
**/
void
gtk_css_value_print (const GtkCssValue *value,
GString *string)
{
gtk_internal_return_if_fail (value != NULL);
gtk_internal_return_if_fail (string != NULL);
value->class ->print (value, string);
}
/**
* gtk_css_value_is_dynamic :
* @ value : a ` GtkCssValue `
*
* A " dynamic " value has a different value at different times . This means that
* the value needs to be animated when time is progressing .
*
* Examples of dynamic values are animated images , such as videos or dynamic shaders .
*
* Use gtk_css_value_get_dynamic_value ( ) to get the value for a given timestamp .
*
* Returns % TRUE if the value is dynamic
*/
gboolean
gtk_css_value_is_dynamic (const GtkCssValue *value)
{
gtk_internal_return_val_if_fail (value != NULL, FALSE );
if (!value->class ->is_dynamic)
return FALSE ;
return value->class ->is_dynamic (value);
}
/**
* gtk_css_value_get_dynamic_value :
* @ value : a ` GtkCssValue `
* @ monotonic_time : the timestamp for which to get the dynamic value
*
* Gets the dynamic value for a given timestamp . If @ monotonic_time is 0 ,
* the default value is returned .
*
* See gtk_css_value_is_dynamic ( ) for details about dynamic values .
*
* Returns : ( transfer full ) : The dynamic value for @ value at the given
* timestamp
*/
GtkCssValue *
gtk_css_value_get_dynamic_value (GtkCssValue *value,
gint64 monotonic_time)
{
gtk_internal_return_val_if_fail (value != NULL, NULL);
if (!value->class ->get_dynamic_value)
return gtk_css_value_ref (value);
return value->class ->get_dynamic_value (value, monotonic_time);
}
Messung V0.5 in Prozent C=98 H=98 G=97
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-07-03)
¤
*© Formatika GbR, Deutschland