Implement height for width for GtkLabel.
2007-06-20 Mathias Hasselmann <mathias.hasselmann@gmx.de> * gtk/gtklabel.c, tests/autotestextendedlayout.c: Implement height for width for GtkLabel. svn path=/branches/extended-layout/; revision=18203
This commit is contained in:
committed by
Mathias Hasselmann
parent
31f1a16eaa
commit
8fc990dfd0
@@ -1,3 +1,8 @@
|
||||
2007-06-20 Mathias Hasselmann <mathias.hasselmann@gmx.de>
|
||||
|
||||
* gtk/gtklabel.c, tests/autotestextendedlayout.c:
|
||||
Implement height for width for GtkLabel.
|
||||
|
||||
2007-06-20 Mathias Hasselmann <mathias.hasselmann@gmx.de>
|
||||
|
||||
* tests/autotestextendedlayout.c: Correct some assumptions,
|
||||
@@ -29,7 +34,7 @@
|
||||
|
||||
2007-05-29 Mathias Hasselmann <mathias.hasselmann@gmx.de>
|
||||
|
||||
* testextendedlayout.c: Create initial heigth-for-width test.
|
||||
* testextendedlayout.c: Create initial height-for-width test.
|
||||
|
||||
2007-05-29 Mathias Hasselmann <mathias.hasselmann@gmx.de>
|
||||
|
||||
|
||||
@@ -4234,17 +4234,40 @@ gtk_label_do_popup (GtkLabel *label,
|
||||
static GtkExtendedLayoutFeatures
|
||||
gtk_label_extended_layout_get_features (GtkExtendedLayout *layout)
|
||||
{
|
||||
return GTK_EXTENDED_LAYOUT_HEIGHT_FOR_WIDTH
|
||||
| GTK_EXTENDED_LAYOUT_NATURAL_SIZE
|
||||
| GTK_EXTENDED_LAYOUT_BASELINES;
|
||||
GtkLabel *label;
|
||||
|
||||
label = GTK_LABEL (layout);
|
||||
|
||||
if (label->wrap)
|
||||
return
|
||||
GTK_EXTENDED_LAYOUT_HEIGHT_FOR_WIDTH |
|
||||
GTK_EXTENDED_LAYOUT_NATURAL_SIZE |
|
||||
GTK_EXTENDED_LAYOUT_BASELINES;
|
||||
|
||||
return
|
||||
GTK_EXTENDED_LAYOUT_NATURAL_SIZE |
|
||||
GTK_EXTENDED_LAYOUT_BASELINES;
|
||||
}
|
||||
|
||||
static gint
|
||||
gtk_label_extended_layout_get_height_for_width (GtkExtendedLayout *layout,
|
||||
gint width)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_LABEL (layout), -1);
|
||||
return -1;
|
||||
PangoLayout *tmp;
|
||||
GtkLabel *label;
|
||||
gint height;
|
||||
|
||||
label = GTK_LABEL (layout);
|
||||
|
||||
g_return_val_if_fail (label->wrap, -1);
|
||||
|
||||
gtk_label_ensure_layout (label);
|
||||
tmp = pango_layout_copy (label->layout);
|
||||
pango_layout_set_width (tmp, PANGO_SCALE * width);
|
||||
pango_layout_get_pixel_size (tmp, NULL, &height);
|
||||
g_object_unref (tmp);
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -4252,6 +4275,7 @@ gtk_label_extended_layout_get_natural_size (GtkExtendedLayout *layout,
|
||||
GtkRequisition *requisition)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_LABEL (layout));
|
||||
g_return_if_reached ();
|
||||
}
|
||||
|
||||
static gint
|
||||
@@ -4263,7 +4287,6 @@ gtk_label_extended_layout_get_baselines (GtkExtendedLayout *layout,
|
||||
GSList *lines;
|
||||
|
||||
label = GTK_LABEL (layout);
|
||||
|
||||
gtk_label_ensure_layout (label);
|
||||
lines = pango_layout_get_lines_readonly (label->layout);
|
||||
num_lines = g_slist_length (lines);
|
||||
|
||||
@@ -1,21 +1,36 @@
|
||||
#include <config.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <glib/gprintf.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define test(condition) \
|
||||
log_test((condition), G_STRFUNC, #condition)
|
||||
#define testf(condition, format, ...) \
|
||||
log_test((condition), G_STRFUNC, \
|
||||
#condition " (" format ")", __VA_ARGS__)
|
||||
#define testi(expected, number) G_STMT_START { \
|
||||
const gint i = (expected), j = (number); \
|
||||
log_test(i == j, G_STRFUNC, #number " is " #expected \
|
||||
" (actual number %d)", j); \
|
||||
} G_STMT_END
|
||||
/*****************************************************************************/
|
||||
|
||||
#define log_test(condition) \
|
||||
log_test_impl(G_STRFUNC, (condition), #condition)
|
||||
#define log_testf(condition, format, ...) \
|
||||
log_test_impl(G_STRFUNC, (condition), #condition " (" format ")", __VA_ARGS__)
|
||||
#define log_testi(expected, number) G_STMT_START { \
|
||||
const gint i = (expected), j = (number); \
|
||||
log_test_impl(G_STRFUNC, i == j, \
|
||||
#number " is " #expected " (actual number %d)", j); \
|
||||
} G_STMT_END
|
||||
|
||||
#define log_info(format, ...) \
|
||||
g_print ("INFO: %s: " format "\n", G_STRFUNC, __VA_ARGS__);
|
||||
#define log_int_array(values, length) \
|
||||
log_int_array_impl (G_STRFUNC, #values, (values), (length))
|
||||
log_int_array_impl (G_STRFUNC, #values, (values), (length))
|
||||
#define log_int(value) \
|
||||
log_info (#value " is %d\n", (value));
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static const gchar lorem_ipsum[] =
|
||||
"<span weight=\"bold\" size=\"xx-large\">"
|
||||
"Lorem ipsum</span> dolor sit amet, consectetuer "
|
||||
"adipiscing elit. Aliquam sed erat. Proin lectus "
|
||||
"orci, venenatis pharetra, egestas id, tincidunt "
|
||||
"vel, eros. Integer fringilla. Aenean justo ipsum, "
|
||||
"luctus ut, volutpat laoreet, vehicula in, libero.";
|
||||
|
||||
static int num_failures = 0;
|
||||
static int num_warnings = 0;
|
||||
@@ -24,6 +39,8 @@ static int num_criticals = 0;
|
||||
|
||||
static GLogFunc default_log_handler;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
log_int_array_impl (const gchar *function,
|
||||
const gchar *var_name,
|
||||
@@ -51,9 +68,9 @@ log_int_array_impl (const gchar *function,
|
||||
}
|
||||
|
||||
static void
|
||||
log_test (gboolean passed,
|
||||
const gchar *function,
|
||||
const gchar *test_name, ...)
|
||||
log_test_impl (const gchar *function,
|
||||
gboolean passed,
|
||||
const gchar *test_name, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *str;
|
||||
@@ -87,8 +104,121 @@ log_override_cb (const gchar *log_domain,
|
||||
(* default_log_handler) (log_domain, log_level, message, user_data);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
test_label (void)
|
||||
gtk_label_test_baselines (void)
|
||||
{
|
||||
GtkExtendedLayout *layout;
|
||||
GtkWidget *widget;
|
||||
GtkLabel *label;
|
||||
|
||||
gint num_baselines;
|
||||
gint *baselines;
|
||||
|
||||
widget = g_object_ref_sink (gtk_label_new (NULL));
|
||||
layout = GTK_EXTENDED_LAYOUT (widget);
|
||||
label = GTK_LABEL (widget);
|
||||
|
||||
baselines = NULL;
|
||||
gtk_label_set_text (label, NULL);
|
||||
num_baselines = gtk_extended_layout_get_baselines (layout, &baselines);
|
||||
log_int_array (baselines, num_baselines);
|
||||
log_testi (1, num_baselines);
|
||||
log_test (NULL != baselines);
|
||||
g_free (baselines);
|
||||
|
||||
baselines = NULL;
|
||||
gtk_label_set_text (label, "");
|
||||
num_baselines = gtk_extended_layout_get_baselines (layout, &baselines);
|
||||
log_int_array (baselines, num_baselines);
|
||||
log_testi (1, num_baselines);
|
||||
log_test (NULL != baselines);
|
||||
g_free (baselines);
|
||||
|
||||
baselines = NULL;
|
||||
gtk_label_set_text (label, "First Line");
|
||||
num_baselines = gtk_extended_layout_get_baselines (layout, &baselines);
|
||||
log_int_array (baselines, num_baselines);
|
||||
log_testi (1, num_baselines);
|
||||
log_test (NULL != baselines);
|
||||
g_free (baselines);
|
||||
|
||||
baselines = NULL;
|
||||
gtk_label_set_text (label, "First Line\n");
|
||||
num_baselines = gtk_extended_layout_get_baselines (layout, &baselines);
|
||||
log_int_array (baselines, num_baselines);
|
||||
log_testi (2, num_baselines);
|
||||
log_test (NULL != baselines);
|
||||
g_free (baselines);
|
||||
|
||||
baselines = NULL;
|
||||
gtk_label_set_text (label, "First Line\nSecond Line");
|
||||
num_baselines = gtk_extended_layout_get_baselines (layout, &baselines);
|
||||
log_int_array (baselines, num_baselines);
|
||||
log_testi (2, num_baselines);
|
||||
log_test (NULL != baselines);
|
||||
g_free (baselines);
|
||||
|
||||
baselines = NULL;
|
||||
gtk_label_set_markup (label, "First Line\n<big>Second Line</big>\nThird Line");
|
||||
num_baselines = gtk_extended_layout_get_baselines (layout, &baselines);
|
||||
log_int_array (baselines, num_baselines);
|
||||
log_testi (3, num_baselines);
|
||||
log_test (NULL != baselines);
|
||||
g_free (baselines);
|
||||
|
||||
g_object_unref (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_test_height_for_width (void)
|
||||
{
|
||||
GtkExtendedLayout *layout;
|
||||
GtkWidget *widget;
|
||||
GtkLabel *label;
|
||||
|
||||
PangoLayout *ref;
|
||||
gint i, cx, cy, rcx, rcy;
|
||||
double cy_min, cy_max;
|
||||
|
||||
widget = g_object_ref_sink (gtk_label_new (NULL));
|
||||
layout = GTK_EXTENDED_LAYOUT (widget);
|
||||
label = GTK_LABEL (widget);
|
||||
|
||||
gtk_label_set_markup (label, lorem_ipsum);
|
||||
gtk_label_set_line_wrap_mode (label, PANGO_WRAP_CHAR);
|
||||
gtk_label_set_line_wrap (label, TRUE);
|
||||
|
||||
ref = pango_layout_copy (gtk_label_get_layout (label));
|
||||
pango_layout_set_width (ref, -1);
|
||||
pango_layout_get_pixel_size (ref, &rcx, &rcy);
|
||||
g_object_unref (ref);
|
||||
|
||||
log_info ("preferred layout size: %d \303\227 %d", rcx, rcy);
|
||||
|
||||
for (i = 5; i >= 1; --i)
|
||||
{
|
||||
cy = gtk_extended_layout_get_height_for_width (layout, cx = rcx * i);
|
||||
log_info ("scale is %d, so width is %d. results in height of %d.", i, cx, cy);
|
||||
log_testi (rcy, cy);
|
||||
}
|
||||
|
||||
cy_min = rcy;
|
||||
cy_max = rcy * 2.5;
|
||||
|
||||
for (i = 2, cx = rcx / 2; cx >= rcy; ++i, cx = rcx / i, cy_min = cy, cy_max += rcy)
|
||||
{
|
||||
cy = gtk_extended_layout_get_height_for_width (layout, cx);
|
||||
log_info ("scale is 1/%d, so width is %d. results in height of %d.", i, cx, cy);
|
||||
log_testf (cy_min <= cy && cy <= cy_max, "%f <= %d <= %f", cy_min, cy, cy_max);
|
||||
}
|
||||
|
||||
g_object_unref (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_test_extended_layout (void)
|
||||
{
|
||||
GtkExtendedLayoutFeatures features;
|
||||
GtkExtendedLayoutIface *iface;
|
||||
@@ -96,83 +226,83 @@ test_label (void)
|
||||
GtkWidget *widget;
|
||||
GtkLabel *label;
|
||||
|
||||
gint *baselines;
|
||||
gint num_baselines;
|
||||
|
||||
widget = g_object_ref_sink (gtk_label_new (NULL));
|
||||
iface = GTK_EXTENDED_LAYOUT_GET_IFACE (widget);
|
||||
layout = GTK_EXTENDED_LAYOUT (widget);
|
||||
label = GTK_LABEL (widget);
|
||||
|
||||
/* basic properties */
|
||||
/* vtable */
|
||||
|
||||
log_test (GTK_IS_EXTENDED_LAYOUT (label));
|
||||
iface = GTK_EXTENDED_LAYOUT_GET_IFACE (label);
|
||||
|
||||
log_test (NULL != iface->get_features);
|
||||
log_test (NULL != iface->get_height_for_width);
|
||||
log_test (NULL == iface->get_width_for_height);
|
||||
log_test (NULL != iface->get_natural_size);
|
||||
log_test (NULL != iface->get_baselines);
|
||||
|
||||
/* feature set */
|
||||
|
||||
test (GTK_IS_EXTENDED_LAYOUT (label));
|
||||
features = gtk_extended_layout_get_features (layout);
|
||||
|
||||
test (NULL != iface->get_features);
|
||||
test (NULL != iface->get_height_for_width);
|
||||
test (NULL == iface->get_width_for_height);
|
||||
test (NULL != iface->get_natural_size);
|
||||
test (NULL != iface->get_baselines);
|
||||
log_test (0 == (features & GTK_EXTENDED_LAYOUT_HEIGHT_FOR_WIDTH));
|
||||
log_test (0 == (features & GTK_EXTENDED_LAYOUT_WIDTH_FOR_HEIGHT));
|
||||
log_test (0 != (features & GTK_EXTENDED_LAYOUT_NATURAL_SIZE));
|
||||
log_test (0 != (features & GTK_EXTENDED_LAYOUT_BASELINES));
|
||||
|
||||
test (0 != (features & GTK_EXTENDED_LAYOUT_HEIGHT_FOR_WIDTH));
|
||||
test (0 == (features & GTK_EXTENDED_LAYOUT_WIDTH_FOR_HEIGHT));
|
||||
test (0 != (features & GTK_EXTENDED_LAYOUT_NATURAL_SIZE));
|
||||
test (0 != (features & GTK_EXTENDED_LAYOUT_BASELINES));
|
||||
gtk_label_set_line_wrap (label, TRUE);
|
||||
features = gtk_extended_layout_get_features (layout);
|
||||
|
||||
log_test (0 != (features & GTK_EXTENDED_LAYOUT_HEIGHT_FOR_WIDTH));
|
||||
log_test (0 == (features & GTK_EXTENDED_LAYOUT_WIDTH_FOR_HEIGHT));
|
||||
log_test (0 != (features & GTK_EXTENDED_LAYOUT_NATURAL_SIZE));
|
||||
log_test (0 != (features & GTK_EXTENDED_LAYOUT_BASELINES));
|
||||
|
||||
g_object_unref (widget);
|
||||
|
||||
/* baseline support */
|
||||
|
||||
baselines = NULL;
|
||||
gtk_label_set_text (label, NULL);
|
||||
num_baselines = gtk_extended_layout_get_baselines (layout, &baselines);
|
||||
log_int_array (baselines, num_baselines);
|
||||
testi (1, num_baselines);
|
||||
test (NULL != baselines);
|
||||
g_free (baselines);
|
||||
gtk_label_test_baselines ();
|
||||
gtk_label_test_height_for_width ();
|
||||
|
||||
baselines = NULL;
|
||||
gtk_label_set_text (label, "");
|
||||
num_baselines = gtk_extended_layout_get_baselines (layout, &baselines);
|
||||
log_int_array (baselines, num_baselines);
|
||||
testi (1, num_baselines);
|
||||
test (NULL != baselines);
|
||||
g_free (baselines);
|
||||
/* height for width */
|
||||
/*
|
||||
PangoLayout *tmp;
|
||||
|
||||
baselines = NULL;
|
||||
gtk_label_set_text (label, "First Line");
|
||||
num_baselines = gtk_extended_layout_get_baselines (layout, &baselines);
|
||||
log_int_array (baselines, num_baselines);
|
||||
testi (1, num_baselines);
|
||||
test (NULL != baselines);
|
||||
g_free (baselines);
|
||||
log_info ("requisition: %d, %d", req.width, req.height);
|
||||
|
||||
baselines = NULL;
|
||||
gtk_label_set_text (label, "First Line\n");
|
||||
num_baselines = gtk_extended_layout_get_baselines (layout, &baselines);
|
||||
log_int_array (baselines, num_baselines);
|
||||
testi (2, num_baselines);
|
||||
test (NULL != baselines);
|
||||
g_free (baselines);
|
||||
for (i = -5; i < 6; ++i)
|
||||
{
|
||||
const gint e = i < 4 ? 1 : 2;
|
||||
|
||||
baselines = NULL;
|
||||
gtk_label_set_text (label, "First Line\nSecond Line");
|
||||
num_baselines = gtk_extended_layout_get_baselines (layout, &baselines);
|
||||
log_int_array (baselines, num_baselines);
|
||||
testi (2, num_baselines);
|
||||
test (NULL != baselines);
|
||||
g_free (baselines);
|
||||
const gdouble sy_lower =
|
||||
i + 1 < 0 ? (abs(i + 1) + 1) :
|
||||
i + 1 > 0 ? 1.0 / (abs(i + 1) + 1) : 1;
|
||||
const gdouble sy_upper =
|
||||
i - e < 0 ? (abs(i - e) + 1) :
|
||||
i - e > 0 ? 1.0 / (abs(i - e) + 1) : 1;
|
||||
|
||||
baselines = NULL;
|
||||
gtk_label_set_markup (label, "First Line\n<big>Second Line</big>\nThird Line");
|
||||
num_baselines = gtk_extended_layout_get_baselines (layout, &baselines);
|
||||
log_int_array (baselines, num_baselines);
|
||||
testi (3, num_baselines);
|
||||
test (NULL != baselines);
|
||||
g_free (baselines);
|
||||
double sy;
|
||||
|
||||
g_object_unref (widget);
|
||||
width =
|
||||
i < 0 ? req.width / (abs(i) + 1) :
|
||||
i > 0 ? req.width * (abs(i) + 1) :
|
||||
req.width;
|
||||
|
||||
height = gtk_extended_layout_get_height_for_width (layout, width);
|
||||
sy = (double)height / req.height;
|
||||
|
||||
log_info ("scale is %s%d, so width is %d, height is %d",
|
||||
i < 0 ? "1/" : "", abs(i) + 1, width, height);
|
||||
|
||||
log_testf (sy_lower <= sy && sy <= sy_upper,
|
||||
"%f <= %f <= %f", sy_lower, sy, sy_upper);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
@@ -180,12 +310,12 @@ main(int argc, char **argv)
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
test_label ();
|
||||
gtk_label_test_extended_layout ();
|
||||
|
||||
testi (0, num_warnings);
|
||||
testi (0, num_errors);
|
||||
testi (0, num_criticals);
|
||||
testi (0, num_failures);
|
||||
log_testi (0, num_warnings);
|
||||
log_testi (0, num_errors);
|
||||
log_testi (0, num_criticals);
|
||||
log_testi (0, num_failures);
|
||||
|
||||
return MAX(0, num_failures - 1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user